YARN-4654. Yarn node label CLI should parse "=" correctly when trying to remove all labels on a node. (Naganarasimha G R via rohithsharmaks)

This commit is contained in:
Rohith Sharma K S 2016-02-18 14:10:37 +05:30
parent 7de70680fe
commit c1afac3a98
3 changed files with 48 additions and 12 deletions

View File

@ -1428,6 +1428,9 @@ Release 2.8.0 - UNRELEASED
YARN-4667. RM Admin CLI for refreshNodesResources throws NPE when nothing YARN-4667. RM Admin CLI for refreshNodesResources throws NPE when nothing
is configured. (Naganarasimha G R via devaraj) is configured. (Naganarasimha G R via devaraj)
YARN-4654. Yarn node label CLI should parse "=" correctly when trying to
remove all labels on a node. (Naganarasimha G R via rohithsharmaks)
Release 2.7.3 - UNRELEASED Release 2.7.3 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -59,8 +59,8 @@
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshAdminAclsRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshAdminAclsRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshClusterMaxPriorityRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshClusterMaxPriorityRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshNodesRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshNodesRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshQueuesRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshNodesResourcesRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshNodesResourcesRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshQueuesRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshServiceAclsRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshServiceAclsRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshSuperUserGroupsConfigurationRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshSuperUserGroupsConfigurationRequest;
import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshUserToGroupsMappingsRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RefreshUserToGroupsMappingsRequest;
@ -592,26 +592,29 @@ private Map<NodeId, Set<String>> buildNodeLabelsMapFromStr(String args) {
continue; continue;
} }
// "," also supported for compatibility
String[] splits = nodeToLabels.split("="); String[] splits = nodeToLabels.split("=");
int index = 0; int labelsStartIndex = 0;
if (splits.length != 2) { String nodeIdStr = splits[0];
if (splits.length == 2) {
splits = splits[1].split(",");
} else if (nodeToLabels.endsWith("=")) {
//case where no labels are mapped to a node
splits = new String[0];
} else {
// "," also supported for compatibility
splits = nodeToLabels.split(","); splits = nodeToLabels.split(",");
index = 1; nodeIdStr = splits[0];
labelsStartIndex = 1;
} }
String nodeIdStr = splits[0];
if (index == 0) {
splits = splits[1].split(",");
}
Preconditions.checkArgument(!nodeIdStr.trim().isEmpty(), Preconditions.checkArgument(!nodeIdStr.trim().isEmpty(),
"node name cannot be empty"); "node name cannot be empty");
NodeId nodeId = ConverterUtils.toNodeIdWithDefaultPort(nodeIdStr); NodeId nodeId = ConverterUtils.toNodeIdWithDefaultPort(nodeIdStr);
map.put(nodeId, new HashSet<String>()); map.put(nodeId, new HashSet<String>());
for (int i = index; i < splits.length; i++) { for (int i = labelsStartIndex; i < splits.length; i++) {
if (!splits[i].trim().isEmpty()) { if (!splits[i].trim().isEmpty()) {
map.get(nodeId).add(splits[i].trim()); map.get(nodeId).add(splits[i].trim());
} }

View File

@ -36,7 +36,9 @@
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ha.HAServiceProtocol; import org.apache.hadoop.ha.HAServiceProtocol;
@ -145,7 +147,20 @@ protected HAServiceTarget resolveTarget(String rmId) {
private void initDummyNodeLabelsManager() { private void initDummyNodeLabelsManager() {
Configuration conf = new YarnConfiguration(); Configuration conf = new YarnConfiguration();
conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true); conf.setBoolean(YarnConfiguration.NODE_LABELS_ENABLED, true);
dummyNodeLabelsManager = new DummyCommonNodeLabelsManager(); dummyNodeLabelsManager = new DummyCommonNodeLabelsManager() {
@Override
public void replaceLabelsOnNode(
Map<NodeId, Set<String>> replaceLabelsToNode) throws IOException {
Iterator<NodeId> iterator = replaceLabelsToNode.keySet().iterator();
while(iterator.hasNext()) {
NodeId nodeId=iterator.next();
if(nodeId.getHost().endsWith("=")){
throw new IOException("Parsing of Input String failed");
}
}
super.replaceLabelsOnNode(replaceLabelsToNode);
}
};
dummyNodeLabelsManager.init(conf); dummyNodeLabelsManager.init(conf);
} }
@ -712,6 +727,21 @@ public void testReplaceMultipleLabelsOnSingleNode() throws Exception {
assertTrue(0 != rmAdminCLI.run(args)); assertTrue(0 != rmAdminCLI.run(args));
} }
@Test
public void testRemoveLabelsOnNodes() throws Exception {
// Successfully replace labels
dummyNodeLabelsManager
.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("x", "y"));
String[] args = { "-replaceLabelsOnNode", "node1=x node2=y",
"-directlyAccessNodeLabelStore" };
assertTrue(0 == rmAdminCLI.run(args));
args = new String[] { "-replaceLabelsOnNode", "node1= node2=",
"-directlyAccessNodeLabelStore" };
assertTrue("Labels should get replaced even '=' is used ",
0 == rmAdminCLI.run(args));
}
private void testError(String[] args, String template, private void testError(String[] args, String template,
ByteArrayOutputStream data, int resultCode) throws Exception { ByteArrayOutputStream data, int resultCode) throws Exception {
int actualResultCode = rmAdminCLI.run(args); int actualResultCode = rmAdminCLI.run(args);