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 05c6cbf..6582186 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 @@ -184,6 +184,12 @@ public class YarnConfiguration extends Configuration { public static final boolean DEFAULT_RM_SCHEDULER_USE_PORT_FOR_NODE_NAME = false; + /** Enable Resource Manager webapp ui actions */ + public static final String RM_WEBAPP_UI_ACTIONS_ENABLED = + RM_PREFIX + "webapp.ui-actions.enabled"; + public static final boolean DEFAULT_RM_WEBAPP_UI_ACTIONS_ENABLED = + false; + /** Whether the RM should enable Reservation System */ public static final String RM_RESERVATION_SYSTEM_ENABLE = RM_PREFIX + "reservation-system.enable"; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppsBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppsBlock.java index 054a1a7..f369f31 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppsBlock.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppsBlock.java @@ -32,12 +32,15 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; 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.rmapp.RMApp; import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.THEAD; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TR; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.apache.hadoop.yarn.webapp.view.HtmlBlock; @@ -46,31 +49,41 @@ import com.google.inject.Inject; class AppsBlock extends HtmlBlock { final ConcurrentMap apps; private final Configuration conf; + private final boolean rmWebAppUIActions; @Inject AppsBlock(ResourceManager rm, ViewContext ctx, Configuration conf) { super(ctx); apps = rm.getRMContext().getRMApps(); this.conf = conf; + this.rmWebAppUIActions = + conf.getBoolean(YarnConfiguration.RM_WEBAPP_UI_ACTIONS_ENABLED, + YarnConfiguration.DEFAULT_RM_WEBAPP_UI_ACTIONS_ENABLED); } @Override public void render(Block html) { - TBODY> tbody = html. - table("#apps"). - thead(). - tr(). - th(".id", "ID"). - th(".user", "User"). - th(".name", "Name"). - th(".type", "Application Type"). - th(".queue", "Queue"). - th(".starttime", "StartTime"). - th(".finishtime", "FinishTime"). - th(".state", "YarnApplicationState"). - th(".finalstatus", "FinalStatus"). - th(".progress", "Progress"). - th(".ui", "Tracking UI")._()._(). - tbody(); + TR>> tr = html. + table("#apps"). + thead(). + tr(); + if (rmWebAppUIActions) { + tr.th(".kill", ""); + } + + TBODY> tbody = tr. + th(".id", "ID"). + th(".user", "User"). + th(".name", "Name"). + th(".type", "Application Type"). + th(".queue", "Queue"). + th(".starttime", "StartTime"). + th(".finishtime", "FinishTime"). + th(".state", "State"). + th(".finalstatus", "FinalStatus"). + th(".progress", "Progress"). + th(".ui", "Tracking UI")._()._(). + tbody(); + Collection reqAppStates = null; String reqStateString = $(APP_STATE); if (reqStateString != null && !reqStateString.isEmpty()) { @@ -88,7 +101,14 @@ class AppsBlock extends HtmlBlock { AppInfo appInfo = new AppInfo(app, true, WebAppUtils.getHttpSchemePrefix(conf)); String percent = String.format("%.1f", appInfo.getProgress()); //AppID numerical value parsed by parseHadoopID in yarn.dt.plugins.js - appsTableData.append("[\"\","); + } else { + appsTableData.append("["); + } + appsTableData.append("\"") .append(appInfo.getAppId()).append("\",\"") .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml( @@ -126,6 +146,9 @@ class AppsBlock extends HtmlBlock { html.script().$type("text/javascript"). _("var appsTableData=" + appsTableData)._(); + html.script().$type("text/javascript"). + _("function confirmAction(href) { b = confirm(\"Are you sure?\"); if (b == true){ location.href = href; } }")._(); + tbody._()._(); } } diff --git b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppBlock.java new file mode 100644 index 0000000..5c0715f --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppBlock.java @@ -0,0 +1,98 @@ +/** +* 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.webapp; + +import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ID; + +import java.io.IOException; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.KillApplicationRequestPBImpl; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.server.resourcemanager.ClientRMService; +import org.apache.hadoop.yarn.server.resourcemanager.RMContext; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; +import org.apache.hadoop.yarn.util.Apps; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; + +import com.google.inject.Inject; + +public class KillAppBlock extends HtmlBlock { + private final ClientRMService client; + private final boolean rmWebAppUIActions; + + + @Inject + KillAppBlock(RMContext rmContext, ViewContext ctx, Configuration conf) { + super(ctx); + this.client = rmContext.getClientRMService(); + this.rmWebAppUIActions = + conf.getBoolean(YarnConfiguration.RM_WEBAPP_UI_ACTIONS_ENABLED, + YarnConfiguration.DEFAULT_RM_WEBAPP_UI_ACTIONS_ENABLED); + } + + @Override + protected void render(Block html) { + if (!rmWebAppUIActions) { + redirect(); + } + + String aid = $(APPLICATION_ID); + if (aid.isEmpty()) { + puts("Bad request: requires application ID"); + return; + } + + ApplicationId appID = null; + try { + appID = Apps.toAppID(aid); + } catch (Exception e) { + puts("Invalid Application ID: " + aid); + return; + } + + RMContext context = getInstance(RMContext.class); + RMApp app = context.getRMApps().get(appID); + if (app.getState() != RMAppState.FINISHED + && app.getState() != RMAppState.KILLED + && app.getState() != RMAppState.FAILED) { + KillApplicationRequest killRequest = new KillApplicationRequestPBImpl(); + killRequest.setApplicationId(appID); + try { + client.forceKillApplication(killRequest); + } catch (YarnException e) { + LOG.error(e.getMessage()); + } + } + + redirect(); + } + + private void redirect() { + try { + response().sendRedirect("/cluster/apps"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppPage.java new file mode 100644 index 0000000..3e9ed69 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/KillAppPage.java @@ -0,0 +1,31 @@ +/** +* 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.webapp; + +import org.apache.hadoop.yarn.webapp.SubView; + +public class KillAppPage extends RmView { + @Override protected void preHead(Page.HTML<_> html) { + commonPreHead(html); + } + + @Override protected Class content() { + return KillAppBlock.class; + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java index c0e6834..2f3e77d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java @@ -59,6 +59,7 @@ public class RMWebApp extends WebApp implements YarnWebParams { route(pajoin("/apps", APP_STATE), RmController.class); route("/cluster", RmController.class, "about"); route(pajoin("/app", APPLICATION_ID), RmController.class, "app"); + route(pajoin("/killapp", APPLICATION_ID), RmController.class, "killapp"); route("/scheduler", RmController.class, "scheduler"); route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue"); route("/nodelabels", RmController.class, "nodelabels"); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java index 972432b..9580f1b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java @@ -54,6 +54,10 @@ public class RmController extends Controller { render(AppPage.class); } + public void killapp() { + render(KillAppPage.class); + } + public void nodes() { render(NodesPage.class); }