YARN-8047. RMWebApp make external class pluggable.

Contributed by Bilwa S T.
This commit is contained in:
Prabhu Joseph 2020-07-07 18:02:29 +05:30 committed by Prabhu Joseph
parent 4f26454a7d
commit 3a4d05b850
4 changed files with 87 additions and 3 deletions

View File

@ -2390,6 +2390,12 @@ public static boolean isAclEnabled(Configuration conf) {
public static final boolean DEFAULT_NM_DOCKER_ALLOW_HOST_PID_NAMESPACE =
false;
public static final String YARN_HTTP_WEBAPP_EXTERNAL_CLASSES =
"yarn.http.rmwebapp.external.classes";
public static final String YARN_HTTP_WEBAPP_SCHEDULER_PAGE =
"hadoop.http.rmwebapp.scheduler.page.class";
/**
* Whether or not users are allowed to request that Docker containers honor
* the debug deletion delay. This is useful for troubleshooting Docker

View File

@ -3330,6 +3330,26 @@
<value>20</value>
</property>
<property>
<description>
Used to specify custom web services for Resourcemanager. Value can be
classnames separated by comma.
Ex: org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebServices,
org.apache.hadoop.yarn.server.resourcemanager.webapp.DummyClass
</description>
<name>yarn.http.rmwebapp.external.classes</name>
<value></value>
</property>
<property>
<description>
Used to specify custom scheduler page
</description>
<name>hadoop.http.rmwebapp.scheduler.page.class</name>
<value></value>
</property>
<property>
<description>The Node Label script to run. Script output Line starting with
"NODE_PARTITION:" will be considered as Node Label Partition. In case of

View File

@ -55,6 +55,7 @@ public void setup() {
bind(RMWebServices.class);
bind(GenericExceptionHandler.class);
bind(RMWebApp.class).toInstance(this);
bindExternalClasses();
if (rm != null) {
bind(ResourceManager.class).toInstance(rm);
@ -97,6 +98,16 @@ public String getRedirectPath() {
return super.getRedirectPath();
}
private void bindExternalClasses() {
YarnConfiguration yarnConf = new YarnConfiguration(rm.getConfig());
Class<?>[] externalClasses = yarnConf
.getClasses(YarnConfiguration.YARN_HTTP_WEBAPP_EXTERNAL_CLASSES);
for (Class<?> c : externalClasses) {
bind(c);
}
}
private String buildRedirectPath() {
// make a copy of the original configuration so not to mutate it. Also use
// an YarnConfiguration to force loading of yarn-site.xml.

View File

@ -21,13 +21,17 @@
import static org.apache.hadoop.yarn.util.StringHelper.join;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.QUEUE_NAME;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
import org.apache.hadoop.yarn.util.StringHelper;
import org.apache.hadoop.yarn.webapp.Controller;
import org.apache.hadoop.yarn.webapp.View;
import org.apache.hadoop.yarn.webapp.YarnWebParams;
import com.google.inject.Inject;
@ -93,9 +97,52 @@ public void scheduler() {
return;
}
if (rs instanceof FifoScheduler) {
setTitle("FIFO Scheduler");
render(DefaultSchedulerPage.class);
return;
}
renderOtherPluginScheduler(rm);
}
private void renderOtherPluginScheduler(ResourceManager rm) {
ResourceScheduler rs = rm.getResourceScheduler();
String schedulerName = rs.getClass().getSimpleName();
Class<? extends View> cls = PluginSchedulerPageHelper
.getPageClass(rm.getConfig());
if (cls != null) {
setTitle(schedulerName);
render(cls);
} else {
LOG.warn(
"Render default scheduler page as scheduler page configured doesn't exist");
setTitle("Default Scheduler");
render(DefaultSchedulerPage.class);
}
}
static class PluginSchedulerPageHelper {
private static boolean hasLoaded = false;
private static Class<? extends View> pageClass = null;
public static Class<? extends View> getPageClass(Configuration conf) {
if (!hasLoaded) {
loadPluginSchedulerPageClass(conf);
hasLoaded = true;
}
return pageClass;
}
private static void loadPluginSchedulerPageClass(Configuration conf) {
Class<?> configuredClass = conf
.getClass(YarnConfiguration.YARN_HTTP_WEBAPP_SCHEDULER_PAGE, null);
if (!View.class.isAssignableFrom(configuredClass)) {
return;
}
pageClass = (Class<? extends View>) configuredClass;
}
}
public void queue() {
setTitle(join("Queue ", get(QUEUE_NAME, "unknown")));