YARN-7442. [YARN-7069] Limit format of resource type name (Contributed by Wangda Tan via Daniel Templeton)

This commit is contained in:
Daniel Templeton 2017-11-13 10:37:30 -08:00
parent fa4b5c669c
commit 2e512f016e
3 changed files with 68 additions and 0 deletions

View File

@ -65,6 +65,11 @@ public class ResourceInformation implements Comparable<ResourceInformation> {
/**
* Set the name for the resource.
*
* A valid resource name must begin with a letter and contain only letters,
* numbers, and any of: '.', '_', or '-'. A valid resource name may also be
* optionally preceded by a name space followed by a slash. A valid name space
* consists of period-separated groups of letters, numbers, and dashes."
*
* @param rName name for the resource
*/
public void setName(String rName) {

View File

@ -62,6 +62,10 @@ public class ResourceUtils {
private static final Pattern RESOURCE_REQUEST_VALUE_PATTERN =
Pattern.compile("^([0-9]+) ?([a-zA-Z]*)$");
private static final Pattern RESOURCE_NAME_PATTERN = Pattern.compile(
"^(((\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?\\.)*"
+ "\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?)/)?\\p{Alpha}([\\w.-]*)$");
private static volatile boolean initializedResources = false;
private static final Map<String, Integer> RESOURCE_NAME_TO_INDEX =
new ConcurrentHashMap<String, Integer>();
@ -208,6 +212,23 @@ public class ResourceUtils {
}
}
@VisibleForTesting
static void validateNameOfResourceNameAndThrowException(String resourceName)
throws YarnRuntimeException {
Matcher matcher = RESOURCE_NAME_PATTERN.matcher(resourceName);
if (!matcher.matches()) {
String message = String.format(
"'%s' is not a valid resource name. A valid resource name must"
+ " begin with a letter and contain only letters, numbers, "
+ "and any of: '.', '_', or '-'. A valid resource name may also"
+ " be optionally preceded by a name space followed by a slash."
+ " A valid name space consists of period-separated groups of"
+ " letters, numbers, and dashes.",
resourceName);
throw new YarnRuntimeException(message);
}
}
@VisibleForTesting
static void initializeResourcesMap(Configuration conf) {
@ -246,6 +267,11 @@ public class ResourceUtils {
}
}
// Validate names of resource information map.
for (String name : resourceInformationMap.keySet()) {
validateNameOfResourceNameAndThrowException(name);
}
checkMandatoryResources(resourceInformationMap);
addMandatoryResources(resourceInformationMap);

View File

@ -24,6 +24,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.ResourceTypes;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.api.records.ResourceInformation;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -311,6 +312,42 @@ public class TestResourceUtils {
}
}
@Test
public void testResourceNameFormatValidation() throws Exception {
String[] validNames = new String[] {
"yarn.io/gpu",
"gpu",
"g_1_2",
"123.io/gpu",
"prefix/resource_1",
"a___-3",
"a....b",
};
String[] invalidNames = new String[] {
"asd/resource/-name",
"prefix/-resource_1",
"prefix/0123resource",
"0123resource",
"-resource_1",
"........abc"
};
for (String validName : validNames) {
ResourceUtils.validateNameOfResourceNameAndThrowException(validName);
}
for (String invalidName : invalidNames) {
try {
ResourceUtils.validateNameOfResourceNameAndThrowException(invalidName);
Assert.fail("Expected to fail name check, the name=" + invalidName
+ " is illegal.");
} catch (YarnRuntimeException e) {
// Expected
}
}
}
public static String setupResourceTypes(Configuration conf, String filename)
throws Exception {
File source = new File(