diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 4b4f581..11802b0 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -1570,14 +1570,10 @@ private static void addDeprecatedKeys() { public static final String YARN_HTTP_POLICY_DEFAULT = HttpConfig.Policy.HTTP_ONLY .name(); - public static final String NODE_LABELS_PREFIX = YARN_PREFIX + "node-labels."; - - /** - * Class for RMNodeLabelsManager Please note this value should be consistent - * in client nodes and RM node(s) + /* + * Following are options for node labels */ - public static final String RM_NODE_LABELS_MANAGER_CLASS = NODE_LABELS_PREFIX - + "manager-class"; + public static final String NODE_LABELS_PREFIX = YARN_PREFIX + "node-labels."; /** URI for NodeLabelManager */ public static final String FS_NODE_LABELS_STORE_ROOT_DIR = NODE_LABELS_PREFIX @@ -1586,6 +1582,14 @@ private static void addDeprecatedKeys() { NODE_LABELS_PREFIX + "fs-store.retry-policy-spec"; public static final String DEFAULT_FS_NODE_LABELS_STORE_RETRY_POLICY_SPEC = "2000, 500"; + + /** + * Flag to indicate if the node labels feature enabled, by default it's + * disabled + */ + public static final String NODE_LABELS_ENABLED = NODE_LABELS_PREFIX + + "enabled"; + public static final boolean DEFAULT_NODE_LABELS_ENABLED = false; public YarnConfiguration() { super(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-distributedshell/src/test/java/org/apache/hadoop/yarn/applications/distributedshell/TestDistributedShell.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-distributedshell/src/test/java/org/apache/hadoop/yarn/applications/distributedshell/TestDistributedShell.java index 1d3a104..46b5850 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-distributedshell/src/test/java/org/apache/hadoop/yarn/applications/distributedshell/TestDistributedShell.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-distributedshell/src/test/java/org/apache/hadoop/yarn/applications/distributedshell/TestDistributedShell.java @@ -80,6 +80,7 @@ protected void setupInternal(int numNodeManager) throws Exception { conf.set("yarn.log.dir", "target"); conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true); conf.set(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class.getName()); + conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); if (yarnCluster == null) { yarnCluster = diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/nodelabels/CommonNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/nodelabels/CommonNodeLabelsManager.java index daefe8d..d42b067 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/nodelabels/CommonNodeLabelsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/nodelabels/CommonNodeLabelsManager.java @@ -40,6 +40,7 @@ import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.event.AsyncDispatcher; import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.EventHandler; @@ -51,6 +52,7 @@ import org.apache.hadoop.yarn.nodelabels.event.UpdateNodeToLabelsMappingsEvent; import org.apache.hadoop.yarn.util.resource.Resources; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; public class CommonNodeLabelsManager extends AbstractService { @@ -63,6 +65,15 @@ private static final Pattern LABEL_PATTERN = Pattern .compile("^[0-9a-zA-Z][0-9a-zA-Z-_]*"); public static final int WILDCARD_PORT = 0; + + /* + * Error messages + */ + @VisibleForTesting + public static final String NODE_LABELS_NOT_ENABLED_ERR = "Node labels not " + + "enabled, you cannot make any changes on node labels, you can set " + + YarnConfiguration.NODE_LABELS_ENABLED + + " to true to enable this feature, please reference to user guide."; /** * If a user doesn't specify label of a queue or node, it belongs @@ -81,6 +92,7 @@ protected final WriteLock writeLock; protected NodeLabelsStore store; + protected boolean nodeLabelsEnabled = false; protected static class Label { public Resource resource; @@ -194,7 +206,13 @@ protected void initDispatcher(Configuration conf) { @Override protected void serviceInit(Configuration conf) throws Exception { - initNodeLabelStore(conf); + // set if node labels enabled + nodeLabelsEnabled = + conf.getBoolean(YarnConfiguration.NODE_LABELS_ENABLED, + YarnConfiguration.DEFAULT_NODE_LABELS_ENABLED); + if (nodeLabelsEnabled) { + initNodeLabelStore(conf); + } labelCollections.put(NO_LABEL, new Label()); } @@ -251,6 +269,10 @@ protected void serviceStop() throws Exception { */ @SuppressWarnings("unchecked") public void addToCluserNodeLabels(Set labels) throws IOException { + if (!nodeLabelsEnabled) { + LOG.error(NODE_LABELS_NOT_ENABLED_ERR); + throw new IOException(NODE_LABELS_NOT_ENABLED_ERR); + } if (null == labels || labels.isEmpty()) { return; } @@ -344,6 +366,10 @@ protected void internalAddLabelsToNode( */ public void addLabelsToNode(Map> addedLabelsToNode) throws IOException { + if (!nodeLabelsEnabled) { + LOG.error(NODE_LABELS_NOT_ENABLED_ERR); + throw new IOException(NODE_LABELS_NOT_ENABLED_ERR); + } addedLabelsToNode = normalizeNodeIdToLabels(addedLabelsToNode); checkAddLabelsToNode(addedLabelsToNode); internalAddLabelsToNode(addedLabelsToNode); @@ -410,6 +436,11 @@ protected void internalRemoveFromClusterNodeLabels(Collection labelsToRe */ public void removeFromClusterNodeLabels(Collection labelsToRemove) throws IOException { + if (!nodeLabelsEnabled) { + LOG.error(NODE_LABELS_NOT_ENABLED_ERR); + throw new IOException(NODE_LABELS_NOT_ENABLED_ERR); + } + labelsToRemove = normalizeLabels(labelsToRemove); checkRemoveFromClusterNodeLabels(labelsToRemove); @@ -521,6 +552,11 @@ protected void internalRemoveLabelsFromNode( public void removeLabelsFromNode(Map> removeLabelsFromNode) throws IOException { + if (!nodeLabelsEnabled) { + LOG.error(NODE_LABELS_NOT_ENABLED_ERR); + throw new IOException(NODE_LABELS_NOT_ENABLED_ERR); + } + removeLabelsFromNode = normalizeNodeIdToLabels(removeLabelsFromNode); checkRemoveLabelsFromNode(removeLabelsFromNode); @@ -595,6 +631,11 @@ protected void internalReplaceLabelsOnNode( */ public void replaceLabelsOnNode(Map> replaceLabelsToNode) throws IOException { + if (!nodeLabelsEnabled) { + LOG.error(NODE_LABELS_NOT_ENABLED_ERR); + throw new IOException(NODE_LABELS_NOT_ENABLED_ERR); + } + replaceLabelsToNode = normalizeNodeIdToLabels(replaceLabelsToNode); checkReplaceLabelsOnNode(replaceLabelsToNode); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/nodelabels/TestCommonNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/nodelabels/TestCommonNodeLabelsManager.java index a56a595..33a35f0 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/nodelabels/TestCommonNodeLabelsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/nodelabels/TestCommonNodeLabelsManager.java @@ -26,6 +26,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.api.records.NodeId; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -41,7 +43,9 @@ @Before public void before() { mgr = new DummyCommonNodeLabelsManager(); - mgr.init(new Configuration()); + Configuration conf = new YarnConfiguration(); + conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); + mgr.init(conf); mgr.start(); } @@ -281,4 +285,58 @@ public void testTrimLabelsWhenModifyLabelsOnNodes() throws IOException { mgr.removeLabelsFromNode(ImmutableMap.of(toNodeId("n1"), toSet(" p2 "))); Assert.assertTrue(mgr.getNodeLabels().isEmpty()); } + + private void assertNodeLabelsDisabledErrorMessage(IOException e) { + Assert.assertEquals(CommonNodeLabelsManager.NODE_LABELS_NOT_ENABLED_ERR, + e.getMessage()); + } + + @Test(timeout = 5000) + public void testNodeLabelsDisabled() throws IOException { + DummyCommonNodeLabelsManager mgr = new DummyCommonNodeLabelsManager(); + Configuration conf = new YarnConfiguration(); + conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); + mgr.init(conf); + mgr.start(); + + // add labels + try { + mgr.addToCluserNodeLabels(ImmutableSet.of("x")); + } catch (IOException e) { + assertNodeLabelsDisabledErrorMessage(e); + } + + // remove labels + try { + mgr.removeFromClusterNodeLabels(ImmutableSet.of("x")); + } catch (IOException e) { + assertNodeLabelsDisabledErrorMessage(e); + } + + // add labels to node + try { + mgr.addLabelsToNode(ImmutableMap.of(NodeId.newInstance("host", 0), + CommonNodeLabelsManager.EMPTY_STRING_SET)); + } catch (IOException e) { + assertNodeLabelsDisabledErrorMessage(e); + } + + // remove labels from node + try { + mgr.removeLabelsFromNode(ImmutableMap.of(NodeId.newInstance("host", 0), + CommonNodeLabelsManager.EMPTY_STRING_SET)); + } catch (IOException e) { + assertNodeLabelsDisabledErrorMessage(e); + } + + // replace labels on node + try { + mgr.replaceLabelsOnNode(ImmutableMap.of(NodeId.newInstance("host", 0), + CommonNodeLabelsManager.EMPTY_STRING_SET)); + } catch (IOException e) { + assertNodeLabelsDisabledErrorMessage(e); + } + + mgr.close(); + } } \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index e0840b6..b6284a7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java @@ -67,7 +67,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher; import org.apache.hadoop.yarn.server.resourcemanager.monitor.SchedulingEditPolicy; import org.apache.hadoop.yarn.server.resourcemanager.monitor.SchedulingMonitor; -import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.MemoryRMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.recovery.NullRMStateStore; import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore; @@ -338,10 +337,7 @@ protected AMLivelinessMonitor createAMLivelinessMonitor() { protected RMNodeLabelsManager createNodeLabelManager() throws InstantiationException, IllegalAccessException { - Class nlmCls = - conf.getClass(YarnConfiguration.RM_NODE_LABELS_MANAGER_CLASS, - MemoryRMNodeLabelsManager.class, RMNodeLabelsManager.class); - return nlmCls.newInstance(); + return new RMNodeLabelsManager(); } protected DelegationTokenRenewer createDelegationTokenRenewer() { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java deleted file mode 100644 index 89053ca..0000000 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.yarn.server.resourcemanager.nodelabels; - -import java.io.IOException; -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.yarn.api.records.NodeId; -import org.apache.hadoop.yarn.nodelabels.NodeLabelsStore; - -public class MemoryRMNodeLabelsManager extends RMNodeLabelsManager { - Map> lastNodeToLabels = null; - Collection lastAddedlabels = null; - Collection lastRemovedlabels = null; - - @Override - public void initNodeLabelStore(Configuration conf) { - this.store = new NodeLabelsStore(this) { - - @Override - public void recover() throws IOException { - // do nothing - } - - @Override - public void removeClusterNodeLabels(Collection labels) - throws IOException { - // do nothing - } - - @Override - public void updateNodeToLabelsMappings( - Map> nodeToLabels) throws IOException { - // do nothing - } - - @Override - public void storeNewClusterNodeLabels(Set label) throws IOException { - // do nothing - } - - @Override - public void close() throws IOException { - // do nothing - } - }; - } - - @Override - protected void initDispatcher(Configuration conf) { - super.dispatcher = null; - } - - @Override - protected void startDispatcher() { - // do nothing - } - - @Override - protected void stopDispatcher() { - // do nothing - } -} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java new file mode 100644 index 0000000..8084b7c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/MemoryRMNodeLabelsManager.java @@ -0,0 +1,90 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.server.resourcemanager.nodelabels; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.api.records.NodeId; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.nodelabels.NodeLabelsStore; + +public class MemoryRMNodeLabelsManager extends RMNodeLabelsManager { + Map> lastNodeToLabels = null; + Collection lastAddedlabels = null; + Collection lastRemovedlabels = null; + + @Override + public void initNodeLabelStore(Configuration conf) { + this.store = new NodeLabelsStore(this) { + + @Override + public void recover() throws IOException { + // do nothing + } + + @Override + public void removeClusterNodeLabels(Collection labels) + throws IOException { + // do nothing + } + + @Override + public void updateNodeToLabelsMappings( + Map> nodeToLabels) throws IOException { + // do nothing + } + + @Override + public void storeNewClusterNodeLabels(Set label) throws IOException { + // do nothing + } + + @Override + public void close() throws IOException { + // do nothing + } + }; + } + + @Override + protected void initDispatcher(Configuration conf) { + super.dispatcher = null; + } + + @Override + protected void startDispatcher() { + // do nothing + } + + @Override + protected void stopDispatcher() { + // do nothing + } + + @Override + protected void serviceInit(Configuration conf) throws Exception { + // always enable node labels while using MemoryRMNodeLabelsManager + conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); + super.serviceInit(conf); + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/TestRMNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/TestRMNodeLabelsManager.java index ed675f3..e8ed03d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/TestRMNodeLabelsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/TestRMNodeLabelsManager.java @@ -26,6 +26,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; import org.apache.hadoop.yarn.nodelabels.NodeLabelTestBase; import org.apache.hadoop.yarn.util.resource.Resources; @@ -47,7 +48,9 @@ @Before public void before() { mgr = new MemoryRMNodeLabelsManager(); - mgr.init(new Configuration()); + Configuration conf = new Configuration(); + conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); + mgr.init(conf); mgr.start(); }