YARN-8405. RM zk-state-store.parent-path ACLs has been changed since HADOOP-14773. Contributed by Íñigo Goiri.

This commit is contained in:
Rohith Sharma K S 2018-06-12 17:13:09 +05:30
parent 2b2f672022
commit 2df73dace0
7 changed files with 53 additions and 30 deletions

View File

@ -290,6 +290,18 @@ public final class ZKCuratorManager {
* @throws Exception If it cannot create the file. * @throws Exception If it cannot create the file.
*/ */
public void createRootDirRecursively(String path) throws Exception { public void createRootDirRecursively(String path) throws Exception {
createRootDirRecursively(path, null);
}
/**
* Utility function to ensure that the configured base znode exists.
* This recursively creates the znode as well as all of its parents.
* @param path Path of the znode to create.
* @param zkAcl ACLs for ZooKeeper.
* @throws Exception If it cannot create the file.
*/
public void createRootDirRecursively(String path, List<ACL> zkAcl)
throws Exception {
String[] pathParts = path.split("/"); String[] pathParts = path.split("/");
Preconditions.checkArgument( Preconditions.checkArgument(
pathParts.length >= 1 && pathParts[0].isEmpty(), pathParts.length >= 1 && pathParts[0].isEmpty(),
@ -298,7 +310,7 @@ public final class ZKCuratorManager {
for (int i = 1; i < pathParts.length; i++) { for (int i = 1; i < pathParts.length; i++) {
sb.append("/").append(pathParts[i]); sb.append("/").append(pathParts[i]);
create(sb.toString()); create(sb.toString(), zkAcl);
} }
} }

View File

@ -35,6 +35,7 @@ import org.apache.hadoop.hdfs.server.federation.store.records.BaseRecord;
import org.apache.hadoop.hdfs.server.federation.store.records.Query; import org.apache.hadoop.hdfs.server.federation.store.records.Query;
import org.apache.hadoop.hdfs.server.federation.store.records.QueryResult; import org.apache.hadoop.hdfs.server.federation.store.records.QueryResult;
import org.apache.hadoop.util.curator.ZKCuratorManager; import org.apache.hadoop.util.curator.ZKCuratorManager;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -70,6 +71,8 @@ public class StateStoreZooKeeperImpl extends StateStoreSerializableImpl {
/** Interface to ZooKeeper. */ /** Interface to ZooKeeper. */
private ZKCuratorManager zkManager; private ZKCuratorManager zkManager;
/** ACLs for ZooKeeper. */
private List<ACL> zkAcl;
@Override @Override
@ -83,6 +86,7 @@ public class StateStoreZooKeeperImpl extends StateStoreSerializableImpl {
try { try {
this.zkManager = new ZKCuratorManager(conf); this.zkManager = new ZKCuratorManager(conf);
this.zkManager.start(); this.zkManager.start();
this.zkAcl = ZKCuratorManager.getZKAcls(conf);
} catch (IOException e) { } catch (IOException e) {
LOG.error("Cannot initialize the ZK connection", e); LOG.error("Cannot initialize the ZK connection", e);
return false; return false;
@ -95,7 +99,7 @@ public class StateStoreZooKeeperImpl extends StateStoreSerializableImpl {
String className, Class<T> clazz) { String className, Class<T> clazz) {
try { try {
String checkPath = getNodePath(baseZNode, className); String checkPath = getNodePath(baseZNode, className);
zkManager.createRootDirRecursively(checkPath); zkManager.createRootDirRecursively(checkPath, zkAcl);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
LOG.error("Cannot initialize ZK node for {}: {}", LOG.error("Cannot initialize ZK node for {}: {}",

View File

@ -73,6 +73,7 @@ import org.apache.hadoop.yarn.server.federation.store.utils.FederationMembership
import org.apache.hadoop.yarn.server.federation.store.utils.FederationPolicyStoreInputValidator; import org.apache.hadoop.yarn.server.federation.store.utils.FederationPolicyStoreInputValidator;
import org.apache.hadoop.yarn.server.federation.store.utils.FederationStateStoreUtils; import org.apache.hadoop.yarn.server.federation.store.utils.FederationStateStoreUtils;
import org.apache.hadoop.yarn.server.records.Version; import org.apache.hadoop.yarn.server.records.Version;
import org.apache.zookeeper.data.ACL;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -133,9 +134,10 @@ public class ZookeeperFederationStateStore implements FederationStateStore {
// Create base znode for each entity // Create base znode for each entity
try { try {
zkManager.createRootDirRecursively(membershipZNode); List<ACL> zkAcl = ZKCuratorManager.getZKAcls(conf);
zkManager.createRootDirRecursively(appsZNode); zkManager.createRootDirRecursively(membershipZNode, zkAcl);
zkManager.createRootDirRecursively(policiesZNode); zkManager.createRootDirRecursively(appsZNode, zkAcl);
zkManager.createRootDirRecursively(policiesZNode, zkAcl);
} catch (Exception e) { } catch (Exception e) {
String errMsg = "Cannot create base directories: " + e.getMessage(); String errMsg = "Cannot create base directories: " + e.getMessage();
FederationStateStoreUtils.logAndThrowStoreException(LOG, errMsg); FederationStateStoreUtils.logAndThrowStoreException(LOG, errMsg);

View File

@ -379,7 +379,7 @@ public class ZKRMStateStore extends RMStateStore {
@Override @Override
public synchronized void startInternal() throws Exception { public synchronized void startInternal() throws Exception {
// ensure root dirs exist // ensure root dirs exist
zkManager.createRootDirRecursively(znodeWorkingPath); zkManager.createRootDirRecursively(znodeWorkingPath, zkAcl);
create(zkRootNodePath); create(zkRootNodePath);
setRootNodeAcls(); setRootNodeAcls();
delete(fencingNodePath); delete(fencingNodePath);

View File

@ -90,7 +90,7 @@ public class ZKConfigurationStore extends YarnConfigurationStore {
this.confStorePath = getNodePath(znodeParentPath, CONF_STORE_PATH); this.confStorePath = getNodePath(znodeParentPath, CONF_STORE_PATH);
this.fencingNodePath = getNodePath(znodeParentPath, FENCING_PATH); this.fencingNodePath = getNodePath(znodeParentPath, FENCING_PATH);
zkManager.createRootDirRecursively(znodeParentPath); zkManager.createRootDirRecursively(znodeParentPath, zkAcl);
zkManager.delete(fencingNodePath); zkManager.delete(fencingNodePath);
if (!zkManager.exists(logsPath)) { if (!zkManager.exists(logsPath)) {

View File

@ -25,6 +25,7 @@ import org.apache.curator.test.TestingServer;
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.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.ha.HAServiceProtocol; import org.apache.hadoop.ha.HAServiceProtocol;
import org.apache.hadoop.ha.HAServiceProtocol.StateChangeRequestInfo; import org.apache.hadoop.ha.HAServiceProtocol.StateChangeRequestInfo;
import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Text;
@ -206,7 +207,7 @@ public class TestZKRMStateStore extends RMStateStoreTestBase {
private RMStateStore createStore(Configuration conf) throws Exception { private RMStateStore createStore(Configuration conf) throws Exception {
workingZnode = "/jira/issue/3077/rmstore"; workingZnode = "/jira/issue/3077/rmstore";
conf.set(YarnConfiguration.RM_ZK_ADDRESS, conf.set(CommonConfigurationKeys.ZK_ADDRESS,
curatorTestingServer.getConnectString()); curatorTestingServer.getConnectString());
conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode); conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode);
conf.setLong(YarnConfiguration.RM_EPOCH, epoch); conf.setLong(YarnConfiguration.RM_EPOCH, epoch);
@ -339,7 +340,7 @@ public class TestZKRMStateStore extends RMStateStoreTestBase {
public RMStateStore getRMStateStore() throws Exception { public RMStateStore getRMStateStore() throws Exception {
YarnConfiguration conf = new YarnConfiguration(); YarnConfiguration conf = new YarnConfiguration();
workingZnode = "/jira/issue/3077/rmstore"; workingZnode = "/jira/issue/3077/rmstore";
conf.set(YarnConfiguration.RM_ZK_ADDRESS, conf.set(CommonConfigurationKeys.ZK_ADDRESS,
curatorTestingServer.getConnectString()); curatorTestingServer.getConnectString());
conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode); conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode);
this.store = new TestZKRMStateStoreInternal(conf, workingZnode) { this.store = new TestZKRMStateStoreInternal(conf, workingZnode) {
@ -380,9 +381,9 @@ public class TestZKRMStateStore extends RMStateStoreTestBase {
conf.set(YarnConfiguration.RM_HA_IDS, rmIds); conf.set(YarnConfiguration.RM_HA_IDS, rmIds);
conf.setBoolean(YarnConfiguration.RECOVERY_ENABLED, true); conf.setBoolean(YarnConfiguration.RECOVERY_ENABLED, true);
conf.set(YarnConfiguration.RM_STORE, ZKRMStateStore.class.getName()); conf.set(YarnConfiguration.RM_STORE, ZKRMStateStore.class.getName());
conf.set(YarnConfiguration.RM_ZK_ADDRESS, conf.set(CommonConfigurationKeys.ZK_ADDRESS,
curatorTestServer.getConnectString()); curatorTestServer.getConnectString());
conf.setInt(YarnConfiguration.RM_ZK_TIMEOUT_MS, ZK_TIMEOUT_MS); conf.setInt(CommonConfigurationKeys.ZK_TIMEOUT_MS, ZK_TIMEOUT_MS);
conf.set(YarnConfiguration.RM_HA_ID, rmId); conf.set(YarnConfiguration.RM_HA_ID, rmId);
conf.set(YarnConfiguration.RM_WEBAPP_ADDRESS, "localhost:0"); conf.set(YarnConfiguration.RM_WEBAPP_ADDRESS, "localhost:0");
conf.setBoolean( conf.setBoolean(
@ -419,31 +420,37 @@ public class TestZKRMStateStore extends RMStateStoreTestBase {
public void testZKRootPathAcls() throws Exception { public void testZKRootPathAcls() throws Exception {
StateChangeRequestInfo req = new StateChangeRequestInfo( StateChangeRequestInfo req = new StateChangeRequestInfo(
HAServiceProtocol.RequestSource.REQUEST_BY_USER); HAServiceProtocol.RequestSource.REQUEST_BY_USER);
String rootPath = String parentPath = YarnConfiguration.DEFAULT_ZK_RM_STATE_STORE_PARENT_PATH;
YarnConfiguration.DEFAULT_ZK_RM_STATE_STORE_PARENT_PATH + "/" + String rootPath = parentPath + "/" + ZKRMStateStore.ROOT_ZNODE_NAME;
ZKRMStateStore.ROOT_ZNODE_NAME;
// Start RM with HA enabled // Start RM with HA enabled
Configuration conf = Configuration conf =
createHARMConf("rm1,rm2", "rm1", 1234, false, curatorTestingServer); createHARMConf("rm1,rm2", "rm1", 1234, false, curatorTestingServer);
conf.set(YarnConfiguration.RM_ZK_ACL, "world:anyone:rwca");
int perm = 23;// rwca=1+2+4+16
ResourceManager rm = new MockRM(conf); ResourceManager rm = new MockRM(conf);
rm.start(); rm.start();
rm.getRMContext().getRMAdminService().transitionToActive(req); rm.getRMContext().getRMAdminService().transitionToActive(req);
List<ACL> acls = ZKRMStateStore stateStore = (ZKRMStateStore) rm.getRMContext().getStateStore();
((ZKRMStateStore)rm.getRMContext().getStateStore()).getACL(rootPath); List<ACL> acls = stateStore.getACL(rootPath);
assertEquals(acls.size(), 2); assertEquals(acls.size(), 2);
// CREATE and DELETE permissions for root node based on RM ID // CREATE and DELETE permissions for root node based on RM ID
verifyZKACL("digest", "localhost", Perms.CREATE | Perms.DELETE, acls); verifyZKACL("digest", "localhost", Perms.CREATE | Perms.DELETE, acls);
verifyZKACL( verifyZKACL(
"world", "anyone", Perms.ALL ^ (Perms.CREATE | Perms.DELETE), acls); "world", "anyone", Perms.ALL ^ (Perms.CREATE | Perms.DELETE), acls);
acls = stateStore.getACL(parentPath);
assertEquals(1, acls.size());
assertEquals(perm, acls.get(0).getPerms());
rm.close(); rm.close();
// Now start RM with HA disabled. NoAuth Exception should not be thrown. // Now start RM with HA disabled. NoAuth Exception should not be thrown.
conf.setBoolean(YarnConfiguration.RM_HA_ENABLED, false); conf.setBoolean(YarnConfiguration.RM_HA_ENABLED, false);
conf.set(YarnConfiguration.RM_ZK_ACL, YarnConfiguration.DEFAULT_RM_ZK_ACL);
rm = new MockRM(conf); rm = new MockRM(conf);
rm.start(); rm.start();
rm.getRMContext().getRMAdminService().transitionToActive(req); rm.getRMContext().getRMAdminService().transitionToActive(req);
acls = ((ZKRMStateStore)rm.getRMContext().getStateStore()).getACL(rootPath); acls = stateStore.getACL(rootPath);
assertEquals(acls.size(), 1); assertEquals(acls.size(), 1);
verifyZKACL("world", "anyone", Perms.ALL, acls); verifyZKACL("world", "anyone", Perms.ALL, acls);
rm.close(); rm.close();
@ -453,7 +460,7 @@ public class TestZKRMStateStore extends RMStateStoreTestBase {
rm = new MockRM(conf); rm = new MockRM(conf);
rm.start(); rm.start();
rm.getRMContext().getRMAdminService().transitionToActive(req); rm.getRMContext().getRMAdminService().transitionToActive(req);
acls = ((ZKRMStateStore)rm.getRMContext().getStateStore()).getACL(rootPath); acls = stateStore.getACL(rootPath);
assertEquals(acls.size(), 2); assertEquals(acls.size(), 2);
verifyZKACL("digest", "localhost", Perms.CREATE | Perms.DELETE, acls); verifyZKACL("digest", "localhost", Perms.CREATE | Perms.DELETE, acls);
verifyZKACL( verifyZKACL(

View File

@ -22,13 +22,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.curator.test.TestingServer; import org.apache.curator.test.TestingServer;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStoreTestBase.TestDispatcher; import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStoreTestBase.TestDispatcher;
import org.apache.hadoop.util.ZKUtil; import org.apache.hadoop.util.ZKUtil;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -38,7 +37,6 @@ import org.junit.Test;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -90,7 +88,7 @@ public class TestZKRMStateStoreZKClientConnections {
public RMStateStore getRMStateStore(Configuration conf) throws Exception { public RMStateStore getRMStateStore(Configuration conf) throws Exception {
String workingZnode = "/Test"; String workingZnode = "/Test";
conf.set(YarnConfiguration.RM_ZK_ADDRESS, conf.set(CommonConfigurationKeys.ZK_ADDRESS,
testingServer.getConnectString()); testingServer.getConnectString());
conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode); conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode);
this.store = new TestZKRMStateStore(conf, workingZnode); this.store = new TestZKRMStateStore(conf, workingZnode);
@ -103,8 +101,8 @@ public class TestZKRMStateStoreZKClientConnections {
TestZKClient zkClientTester = new TestZKClient(); TestZKClient zkClientTester = new TestZKClient();
final String path = "/test"; final String path = "/test";
YarnConfiguration conf = new YarnConfiguration(); YarnConfiguration conf = new YarnConfiguration();
conf.setInt(YarnConfiguration.RM_ZK_TIMEOUT_MS, ZK_TIMEOUT_MS); conf.setInt(CommonConfigurationKeys.ZK_TIMEOUT_MS, ZK_TIMEOUT_MS);
conf.setLong(YarnConfiguration.RM_ZK_RETRY_INTERVAL_MS, 100); conf.setLong(CommonConfigurationKeys.ZK_RETRY_INTERVAL_MS, 100);
final ZKRMStateStore store = final ZKRMStateStore store =
(ZKRMStateStore) zkClientTester.getRMStateStore(conf); (ZKRMStateStore) zkClientTester.getRMStateStore(conf);
TestDispatcher dispatcher = new TestDispatcher(); TestDispatcher dispatcher = new TestDispatcher();
@ -133,7 +131,7 @@ public class TestZKRMStateStoreZKClientConnections {
public void testSetZKAcl() { public void testSetZKAcl() {
TestZKClient zkClientTester = new TestZKClient(); TestZKClient zkClientTester = new TestZKClient();
YarnConfiguration conf = new YarnConfiguration(); YarnConfiguration conf = new YarnConfiguration();
conf.set(YarnConfiguration.RM_ZK_ACL, "world:anyone:rwca"); conf.set(CommonConfigurationKeys.ZK_ACL, "world:anyone:rwca");
try { try {
zkClientTester.store.delete(zkClientTester.store zkClientTester.store.delete(zkClientTester.store
.znodeWorkingPath); .znodeWorkingPath);
@ -146,7 +144,7 @@ public class TestZKRMStateStoreZKClientConnections {
public void testInvalidZKAclConfiguration() { public void testInvalidZKAclConfiguration() {
TestZKClient zkClientTester = new TestZKClient(); TestZKClient zkClientTester = new TestZKClient();
YarnConfiguration conf = new YarnConfiguration(); YarnConfiguration conf = new YarnConfiguration();
conf.set(YarnConfiguration.RM_ZK_ACL, "randomstring&*"); conf.set(CommonConfigurationKeys.ZK_ACL, "randomstring&*");
try { try {
zkClientTester.getRMStateStore(conf); zkClientTester.getRMStateStore(conf);
fail("ZKRMStateStore created with bad ACL"); fail("ZKRMStateStore created with bad ACL");
@ -163,10 +161,10 @@ public class TestZKRMStateStoreZKClientConnections {
public void testZKAuths() throws Exception { public void testZKAuths() throws Exception {
TestZKClient zkClientTester = new TestZKClient(); TestZKClient zkClientTester = new TestZKClient();
YarnConfiguration conf = new YarnConfiguration(); YarnConfiguration conf = new YarnConfiguration();
conf.setInt(YarnConfiguration.RM_ZK_NUM_RETRIES, 1); conf.setInt(CommonConfigurationKeys.ZK_NUM_RETRIES, 1);
conf.setInt(YarnConfiguration.RM_ZK_TIMEOUT_MS, ZK_TIMEOUT_MS); conf.setInt(CommonConfigurationKeys.ZK_TIMEOUT_MS, ZK_TIMEOUT_MS);
conf.set(YarnConfiguration.RM_ZK_ACL, TEST_ACL); conf.set(CommonConfigurationKeys.ZK_ACL, TEST_ACL);
conf.set(YarnConfiguration.RM_ZK_AUTH, TEST_AUTH_GOOD); conf.set(CommonConfigurationKeys.ZK_AUTH, TEST_AUTH_GOOD);
zkClientTester.getRMStateStore(conf); zkClientTester.getRMStateStore(conf);
} }