Repository: hadoop Updated Branches: refs/heads/trunk cc51607cc -> 154449fbd
http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebTerminal.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebTerminal.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebTerminal.java new file mode 100644 index 0000000..8589b94 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebTerminal.java @@ -0,0 +1,124 @@ +/** +* 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.nodemanager.webapp; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; + +import javax.ws.rs.core.MediaType; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.http.JettyUtils; +import org.apache.hadoop.util.NodeHealthScriptRunner; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.server.nodemanager.Context; +import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService; +import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService; +import org.apache.hadoop.yarn.server.nodemanager.NodeManager; +import org.apache.hadoop.yarn.server.nodemanager.ResourceView; +import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource.Builder; + +/** + * Unit test for hosting web terminal servlet in node manager. + */ +public class TestNMWebTerminal { + private static final File TESTROOTDIR = new File("target", + TestNMWebServer.class.getSimpleName()); + private static File TESTLOGDIR = new File("target", + TestNMWebServer.class.getSimpleName() + "LogDir"); + private NodeHealthCheckerService healthChecker; + private WebServer server; + private int port; + + private NodeHealthCheckerService createNodeHealthCheckerService( + Configuration conf) { + NodeHealthScriptRunner scriptRunner = NodeManager + .getNodeHealthScriptRunner(conf); + LocalDirsHandlerService dirsHandler = new LocalDirsHandlerService(); + return new NodeHealthCheckerService(scriptRunner, dirsHandler); + } + + private int startNMWebAppServer(String webAddr) { + Configuration conf = new Configuration(); + Context nmContext = new NodeManager.NMContext(null, null, null, null, + null, false, conf); + ResourceView resourceView = new ResourceView() { + @Override + public long getVmemAllocatedForContainers() { + return 0; + } + @Override + public long getPmemAllocatedForContainers() { + return 0; + } + @Override + public long getVCoresAllocatedForContainers() { + return 0; + } + @Override + public boolean isVmemCheckEnabled() { + return true; + } + @Override + public boolean isPmemCheckEnabled() { + return true; + } + }; + conf.set(YarnConfiguration.NM_LOCAL_DIRS, TESTROOTDIR.getAbsolutePath()); + conf.set(YarnConfiguration.NM_LOG_DIRS, TESTLOGDIR.getAbsolutePath()); + healthChecker = createNodeHealthCheckerService(conf); + healthChecker.init(conf); + LocalDirsHandlerService dirsHandler = healthChecker.getDiskHandler(); + conf.set(YarnConfiguration.NM_WEBAPP_ADDRESS, webAddr); + server = new WebServer(nmContext, resourceView, + new ApplicationACLsManager(conf), dirsHandler); + server.init(conf); + server.start(); + return server.getPort(); + } + + @Before + public void setUp() { + port = startNMWebAppServer("0.0.0.0:0"); + } + + @After + public void tearDown() throws IOException { + server.close(); + healthChecker.close(); + } + + @Test + public void testWebTerminal() { + Client client = Client.create(); + Builder builder = client.resource("http://127.0.0.1:" + port + + "/terminal/terminal.template").accept("text/html"); + ClientResponse response = builder.get(ClientResponse.class); + assertEquals(MediaType.TEXT_HTML + "; " + JettyUtils.UTF_8, + response.getType().toString()); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml index 7fda987..b76132d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml @@ -118,11 +118,52 @@ <exclude>bower_components/**/*</exclude> <exclude>tmp/**/*</exclude> <exclude>dist/**/*</exclude> + <exclude>terminal/**/*</exclude> </excludes> </resource> </resources> </configuration> </execution> + <execution> + <id>copy-terminal</id> + <!-- here the phase you need --> + <phase>compile</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${webappDir}/dist</outputDirectory> + <resources> + <resource> + <directory>${basedir}/src/main/webapp</directory> + <filtering>true</filtering> + <includes> + <include>terminal/**/*</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + <execution> + <id>copy-xterm</id> + <!-- here the phase you need --> + <phase>compile</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${webappDir}/dist/terminal/xterm</outputDirectory> + <resources> + <resource> + <directory>${basedir}/target/webapp/node_modules/xterm</directory> + <filtering>true</filtering> + <includes> + <include>dist/**/*</include> + </includes> + </resource> + </resources> + </configuration> + </execution> </executions> </plugin> http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js index f09f42e..70f5898 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js @@ -26,6 +26,7 @@ export default Ember.Component.extend({ searchType: 'manual', }), graphDrawn: false, + userInfo: null, actions: { changeViewType(param) { @@ -417,7 +418,14 @@ export default Ember.Component.extend({ id: 'id', headerTitle: 'Container ID', contentPath: 'id', - minWidth: '350px' + cellComponentName: 'em-table-html-cell', + minWidth: '350px', + getCellContent: function(row) { + var termLink = self.checkHttpProtocol(row.get('nodeHttpAddress')); + var containerId = row.get('id'); + var requestedUser = self.get('requestedUser'); + return `<a href="${termLink}/terminal/terminal.template?container=${containerId}&user.name=${requestedUser}" target="_blank">${containerId}</a>`; + } }, { id: 'startedTime', headerTitle: 'Started Time', @@ -503,5 +511,12 @@ export default Ember.Component.extend({ prop = 'http://' + prop; } return prop; - } + }, + + requestedUser: function() { + if (this.get('userInfo')) { + return this.get('userInfo.requestedUser'); + } + return ''; + }.property('userInfo'), }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js index 7482a2f..c313f02 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js @@ -65,5 +65,5 @@ export default DS.Model.extend({ masterNodeURL: function() { var addr = encodeURIComponent(this.get("nodeHttpAddress")); return `#/yarn-node/${this.get("nodeId")}/${addr}/info/`; - }.property("nodeId", "nodeHttpAddress"), + }.property("nodeId", "nodeHttpAddress") }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-timeline-container.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-timeline-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-timeline-container.js index 9384418..8958591 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-timeline-container.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-timeline-container.js @@ -66,5 +66,5 @@ export default DS.Model.extend({ masterNodeURL: function() { var addr = encodeURIComponent(this.get("nodeHttpAddress")); return `#/yarn-node/${this.get("nodeId")}/${addr}/info/`; - }.property("nodeId", "nodeHttpAddress"), + }.property("nodeId", "nodeHttpAddress") }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js index 829cfe9..69c26c9 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js @@ -37,6 +37,11 @@ export default AbstractRoute.extend(AppAttemptMixin, { }); }, + afterModel(model) { + const appContrl = this.controllerFor('application'); + model.userInfo = appContrl.get('userInfo'); + }, + unloadAll() { this.store.unloadAll('yarn-app-attempt'); this.store.unloadAll('yarn-timeline-appattempt'); http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs index 139b7eb..935cf94 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs @@ -60,5 +60,11 @@ <td><a href="{{prepend-protocol container.logUrl}}" target="_blank">Link</a></td> </tr> {{/if}} + {{#if container.nodeHttpAddress}} + <tr> + <td>Terminal</td> + <td><a href="{{container.nodeHttpAddress}}/terminal/terminal.template?container={{container.id}}&user.name={{requestedUser}}" target="_blank">Link</a></td> + </tr> + {{/if}} </tbody> </table> http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs index 7e7f783..c358ce5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs @@ -52,7 +52,7 @@ {{#if attemptModel}} {{app-attempt-table attempt=selected}} {{else}} - {{container-table container=selected}} + {{container-table container=selected requestedUser=requestedUser}} {{/if}} </div> </div> http://git-wip-us.apache.org/repos/asf/hadoop/blob/154449fb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs index 044b9b1..05d2f21 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs @@ -98,6 +98,7 @@ attemptModel=false changeViewType="changeViewType" viewType=viewType + userInfo=model.userInfo }} {{else}} <div class="col-md-12 container-fluid"> --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org