소스 검색

AMBARI-1059. Refactor cluster management. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418965 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 년 전
부모
커밋
0769fc6f9f
56개의 변경된 파일753개의 추가작업 그리고 342개의 파일을 삭제
  1. 58 1
      ambari-web/app/assets/data/hosts/hosts.json
  2. 0 1
      ambari-web/app/controllers.js
  3. 3 4
      ambari-web/app/controllers/global/cluster_controller.js
  4. 5 1
      ambari-web/app/controllers/installer.js
  5. 7 1
      ambari-web/app/controllers/main/charts/heatmap.js
  6. 0 66
      ambari-web/app/controllers/main/dashboard.js
  7. 18 3
      ambari-web/app/controllers/main/host/add_controller.js
  8. 2 1
      ambari-web/app/controllers/main/service.js
  9. 26 8
      ambari-web/app/controllers/main/service/add_controller.js
  10. 1 1
      ambari-web/app/controllers/wizard/step10_controller.js
  11. 4 0
      ambari-web/app/controllers/wizard/step6_controller.js
  12. 11 8
      ambari-web/app/controllers/wizard/step8_controller.js
  13. 4 0
      ambari-web/app/controllers/wizard/step9_controller.js
  14. 2 13
      ambari-web/app/data/config_properties.js
  15. 5 4
      ambari-web/app/data/review_configs.js
  16. 3 2
      ambari-web/app/mappers/hosts_mapper.js
  17. 1 1
      ambari-web/app/mappers/users_mapper.js
  18. 3 1
      ambari-web/app/messages.js
  19. 10 1
      ambari-web/app/models/host.js
  20. 3 1
      ambari-web/app/models/host_component.js
  21. 31 1
      ambari-web/app/models/service.js
  22. 9 2
      ambari-web/app/models/user.js
  23. 5 2
      ambari-web/app/routes/add_host_routes.js
  24. 12 3
      ambari-web/app/routes/add_service_routes.js
  25. 1 1
      ambari-web/app/routes/installer.js
  26. 5 1
      ambari-web/app/routes/main.js
  27. 8 1
      ambari-web/app/styles/application.less
  28. 124 0
      ambari-web/app/styles/apps.less
  29. 3 0
      ambari-web/app/templates/main/charts/heatmap/heatmap_rack.hbs
  30. 1 1
      ambari-web/app/templates/main/charts/linear_time.hbs
  31. 0 55
      ambari-web/app/templates/main/dashboard.hbs
  32. 1 1
      ambari-web/app/templates/main/dashboard/service/hbase.hbs
  33. 1 1
      ambari-web/app/templates/main/dashboard/service/hdfs.hbs
  34. 1 1
      ambari-web/app/templates/main/dashboard/service/hive.hbs
  35. 1 1
      ambari-web/app/templates/main/dashboard/service/mapreduce.hbs
  36. 1 1
      ambari-web/app/templates/main/dashboard/service/oozie.hbs
  37. 1 1
      ambari-web/app/templates/main/dashboard/service/zookeeper.hbs
  38. 1 1
      ambari-web/app/templates/main/host.hbs
  39. 111 0
      ambari-web/app/templates/main/service/info/client_summary.hbs
  40. 5 1
      ambari-web/app/templates/main/service/item.hbs
  41. 5 1
      ambari-web/app/templates/main/service/menu_item.hbs
  42. 1 1
      ambari-web/app/templates/wizard/step7.hbs
  43. 2 0
      ambari-web/app/templates/wizard/step9.hbs
  44. 3 2
      ambari-web/app/utils/data_table.js
  45. 88 33
      ambari-web/app/views/common/chart/linear_time.js
  46. 11 1
      ambari-web/app/views/main/admin/user/edit.js
  47. 15 42
      ambari-web/app/views/main/apps_view.js
  48. 1 1
      ambari-web/app/views/main/dashboard/service.js
  49. 19 1
      ambari-web/app/views/main/host.js
  50. 8 5
      ambari-web/app/views/main/service/info/menu.js
  51. 81 55
      ambari-web/app/views/main/service/info/summary.js
  52. 11 4
      ambari-web/app/views/main/service/item.js
  53. 12 1
      ambari-web/app/views/main/service/menu.js
  54. 2 2
      ambari-web/app/views/wizard/controls_view.js
  55. 1 0
      ambari-web/app/views/wizard/step9_view.js
  56. 5 0
      ambari-web/pom.xml

+ 58 - 1
ambari-web/app/assets/data/hosts/hosts.json

@@ -14,6 +14,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -88,7 +93,11 @@
         "host_name" : "dev2.hortonworks.com",
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
-        "os_type" : "centos6",
+        "os_type" : "centos6","load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_five" : 8.68588888889
+        },
+
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -164,6 +173,10 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -238,6 +251,10 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -304,6 +321,9 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -370,6 +390,9 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -436,6 +459,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -502,6 +530,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -568,6 +601,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -634,6 +672,10 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -700,6 +742,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -766,6 +813,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [
@@ -832,6 +884,11 @@
         "disk_info" : "[{\"available\":\"47295056\",\"mountpoint\":\"/\",\"used\":\"3786948\",\"percent\":\"8%\",\"size\":\"51606140\",\"type\":\"ext4\"},{\"available\":\"1542800\",\"mountpoint\":\"/dev/shm\",\"used\":\"248\",\"percent\":\"1%\",\"size\":\"1543048\",\"type\":\"tmpfs\"},{\"available\":\"432210\",\"mountpoint\":\"/boot\",\"used\":\"38034\",\"percent\":\"9%\",\"size\":\"495844\",\"type\":\"ext4\"},{\"available\":\"44459872\",\"mountpoint\":\"/home\",\"used\":\"184220\",\"percent\":\"1%\",\"size\":\"47033288\",\"type\":\"ext4\"},{\"available\":\"902105496\",\"mountpoint\":\"/media/sf_ambari\",\"used\":\"74551908\",\"percent\":\"8%\",\"size\":\"976657404\",\"type\":\"vboxsf\"}]",
         "last_heartbeat_time" : 1352461939047,
         "os_type" : "centos6",
+        "load" : {
+          "load_fifteen" : 9.13213888889,
+          "load_one" : 8.24583333333,
+          "load_five" : 8.68588888889
+        },
         "ip" : "10.0.2.15"
       },
       "host_components" : [

+ 0 - 1
ambari-web/app/controllers.js

@@ -42,7 +42,6 @@ require('controllers/main/alert');
 require('controllers/main/host');
 require('controllers/main/host/details');
 require('controllers/main/host/add_controller');
-require('controllers/main/dashboard');
 require('controllers/main/charts');
 require('controllers/main/charts/heatmap_metrics/heatmap_metric');
 require('controllers/main/charts/heatmap_metrics/heatmap_metric_processrun');

+ 3 - 4
ambari-web/app/controllers/global/cluster_controller.js

@@ -97,8 +97,7 @@ App.ClusterController = Em.Controller.extend({
           if (nagiosSvcComponent) {
             var hostName = nagiosSvcComponent.get('host.hostName');
             if (hostName) {
-              return null;
-              //return "http://"+hostName+"/nagios";
+              return "http://"+hostName+"/nagios";
             }
           }
         }
@@ -198,7 +197,7 @@ App.ClusterController = Em.Controller.extend({
         console.log('update finished')
         setTimeout(function(){
           self.updateStatus();
-        }, 1000);
+        }, 3000);
       }
     }, null);
   },
@@ -370,7 +369,7 @@ App.ClusterController = Em.Controller.extend({
 
     setTimeout(function(){
       self.updateStatus();
-    }, 1000);
+    }, 8000);
 
   },
 

+ 5 - 1
ambari-web/app/controllers/installer.js

@@ -772,7 +772,11 @@ App.InstallerController = Em.Controller.extend({
    * Generate clients list for selected services and save it to model
    * called form stepController step8WizardController or step9WizardController
    */
-  installServices: function () {
+  installServices: function (isRetry) {
+    if(!isRetry && this.get('content.cluster.requestId')){
+      return;
+    }
+
     var self = this;
     var clusterName = this.get('content.cluster.name');
     var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?state=INIT';

+ 7 - 1
ambari-web/app/controllers/main/charts/heatmap.js

@@ -27,7 +27,13 @@ App.MainChartsHeatmapController = Em.Controller.extend({
   }) ],
 
   selectedMetric: null,
-
+  /**
+   *  route on host detail page
+   * @param event
+   */
+  routeHostDetail: function(event){
+    App.router.transitionTo('main.hostDetails.summary', event.context)
+  },
   showHeatMapMetric: function (event) {
     var metricItem = event.context;
     if (metricItem) {

+ 0 - 66
ambari-web/app/controllers/main/dashboard.js

@@ -1,66 +0,0 @@
-/**
- * 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.
- */
-
-var App = require('app');
-
-App.MainDashboardController = Em.Controller.extend({
-  name:'mainDashboardController',
-  alerts: function(){
-    return App.router.get('clusterController.alerts');
-  }.property('App.router.clusterController.alerts'),
-
-  alertsFilteredByName: 'All',
-  alertsFilteredByType: 'All',
-  alertsFilter: function(event) {
-    if (event.context && event.context.model && event.context.model.get('serviceName')){
-      this.set('alertsFilteredByName', event.context.model.get('displayName'));
-      this.set('alertsFilteredByType', event.context.model.get('serviceName'));
-    } else {
-      this.set('alertsFilteredByName', 'All');
-      this.set('alertsFilteredByType', 'All');
-    }
-  },
-  /**
-   * We do not want to re-get all the data everytime the filter
-   * is changed. Hence we just filtered the alerts got during page
-   * load.
-   */
-  displayAlerts: function(){
-    if(this.get('alertsFilteredByType')=='All')
-      return this.get('alerts');
-    else
-      var type = this.get('alertsFilteredByType').toLowerCase();
-      return this.get('alerts').filter(function(item){
-        var serviceType = item.get('serviceType');
-        return serviceType && serviceType.toLowerCase()==type.toLowerCase();
-      });
-  }.property('alerts', 'alertsFilteredByType'),
-  
-  nagiosUrl: function(){
-    return App.router.get('clusterController.nagiosUrl');
-  }.property('App.router.clusterController.nagiosUrl'),
-  
-  isNagiosInstalled: function(){
-    return App.router.get('clusterController.isNagiosInstalled');
-  }.property('App.router.clusterController.isNagiosInstalled'),
-  
-  alertsCount: function() {
-    var alerts = this.get('alerts');
-    return alerts ? alerts.filterProperty('status', 'corrupt').length : 0;
-  }.property('alerts')
-});

+ 18 - 3
ambari-web/app/controllers/main/host/add_controller.js

@@ -198,6 +198,17 @@ App.AddHostController = Em.Controller.extend({
     console.log("AddHostController:loadClusterInfo: loaded data ", cluster);
   },
 
+  /**
+   * save status of the cluster. This is called from step8 and step9 to persist install and start requestId
+   * @param clusterStatus object with status, isCompleted, requestId, isInstallError and isStartError field.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    clusterStatus.name = this.get('content.cluster.name');
+    this.set('content.cluster', clusterStatus);
+    console.log('called saveClusterStatus ' + JSON.stringify(clusterStatus));
+    App.db.setClusterStatus(clusterStatus);
+  },
+
   /**
    * Temporary function for wizardStep9, before back-end integration
    */
@@ -728,7 +739,11 @@ App.AddHostController = Em.Controller.extend({
    * Generate clients list for selected services and save it to model
    * @param stepController step8WizardController or step9WizardController
    */
-  installServices: function () {
+  installServices: function (isRetry) {
+    if(!isRetry && this.get('content.cluster.requestId')){
+      return;
+    }
+
     var self = this;
     var clusterName = this.get('content.cluster.name');
     var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?state=INIT';
@@ -757,7 +772,7 @@ App.AddHostController = Em.Controller.extend({
             isCompleted: false,
             installStartTime: installSartTime
           };
-          //self.saveClusterStatus(clusterStatus);
+          self.saveClusterStatus(clusterStatus);
         } else {
           console.log('ERROR: Error occurred in parsing JSON data');
         }
@@ -773,7 +788,7 @@ App.AddHostController = Em.Controller.extend({
           isInstallError: true,
           isCompleted: false
         };
-        //self.saveClusterStatus(clusterStatus);
+        self.saveClusterStatus(clusterStatus);
       },
 
       statusCode: require('data/statusCodes')

+ 2 - 1
ambari-web/app/controllers/main/service.js

@@ -20,5 +20,6 @@ var App = require('app');
 
 App.MainServiceController = Em.ArrayController.extend({
   name:'mainServiceController',
-  content: App.Service.find()
+  content: App.Service.find(),
+  additionalMenuItem:Em.Object.create({ id:'Clients', displayName:'Clients', isClients:true })
 })

+ 26 - 8
ambari-web/app/controllers/main/service/add_controller.js

@@ -287,7 +287,11 @@ App.AddServiceController = Em.Controller.extend({
     });
     this.set('content.services', servicesInfo);
     console.log('AddServiceController.loadServices: loaded data ', servicesInfo);
-    console.log('selected services ', servicesInfo.filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName'));
+
+    var serviceNames = servicesInfo.filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName');
+    console.log('selected services ', serviceNames);
+
+    this.set('content.missSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE'));
   },
 
   /**
@@ -304,6 +308,8 @@ App.AddServiceController = Em.Controller.extend({
     this.set('content.selectedServiceNames', serviceNames);
     App.db.setSelectedServiceNames(serviceNames);
     console.log('AddServiceController.selectedServiceNames:', serviceNames);
+
+    this.set('content.missSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE'));
   },
 
   /**
@@ -328,6 +334,8 @@ App.AddServiceController = Em.Controller.extend({
     console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
+
+    this.set('content.missMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
   },
 
   /**
@@ -348,6 +356,8 @@ App.AddServiceController = Em.Controller.extend({
     }
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("AddServiceController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
+
+    this.set('content.missMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
   },
 
   /**
@@ -556,12 +566,16 @@ App.AddServiceController = Em.Controller.extend({
   dataLoading: function(){
     var dfd = $.Deferred();
     this.connectOutlet('loading');
-    var interval = setInterval(function(){
-      if (App.router.get('clusterController.isLoaded')){
-        dfd.resolve();
-        clearInterval(interval);
-      }
-    },50);
+    if (App.router.get('clusterController.isLoaded')){
+      dfd.resolve();
+    } else{
+      var interval = setInterval(function(){
+        if (App.router.get('clusterController.isLoaded')){
+          dfd.resolve();
+          clearInterval(interval);
+        }
+      },50);
+    }
     return dfd.promise();
   },
   /**
@@ -666,7 +680,11 @@ App.AddServiceController = Em.Controller.extend({
    * Generate clients list for selected services and save it to model
    * @param stepController step8WizardController or step9WizardController
    */
-  installServices: function () {
+  installServices: function (isRetry) {
+    if(!isRetry && this.get('content.cluster.requestId')){
+      return;
+    }
+
     var self = this;
     var clusterName = this.get('content.cluster.name');
     var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?state=INIT';

+ 1 - 1
ambari-web/app/controllers/wizard/step10_controller.js

@@ -275,7 +275,7 @@ App.WizardStep10Controller = Em.Controller.extend({
 
   loadOozieServer: function (component) {
     if (component.get('hostName')) {
-      var statement = 'Hive Metastore installed on ' + component.get('hostName');
+      var statement = 'Oozie Server installed on ' + component.get('hostName');
       this.get('clusterInfo').findProperty('id', 2).get('status').pushObject(Ember.Object.create({
         id: 1,
         color: 'text-info',

+ 4 - 0
ambari-web/app/controllers/wizard/step6_controller.js

@@ -152,6 +152,10 @@ App.WizardStep6Controller = Em.Controller.extend({
     console.log("WizardStep6Controller: Loading step6: Assign Slaves");
     this.clearStep();
     this.renderSlaveHosts();
+
+    if(this.get('content.missSlavesStep')){
+      App.router.send('next');
+    }
   },
 
   /**

+ 11 - 8
ambari-web/app/controllers/wizard/step8_controller.js

@@ -514,7 +514,8 @@ App.WizardStep8Controller = Em.Controller.extend({
           this.loadOozieServerValue(_component);
           break;
         case 'Database':
-          this.loadOozieDbValue(_component);
+          // TODO: uncomment when ready to integrate with Oozie Database other than Derby
+          // this.loadOozieDbValue(_component);
           break;
         default:
       }
@@ -600,13 +601,15 @@ App.WizardStep8Controller = Em.Controller.extend({
       //return;
     }
 
-    this.createCluster();
-    this.createSelectedServices();
-    this.createConfigurations();
-    this.applyCreatedConfToServices();
-    this.createComponents();
-    this.registerHostsToCluster();
-    this.createHostComponents();
+    if(!this.get('content.cluster.requestId')){
+      this.createCluster();
+      this.createSelectedServices();
+      this.createConfigurations();
+      this.applyCreatedConfToServices();
+      this.createComponents();
+      this.registerHostsToCluster();
+      this.createHostComponents();
+    }
 
     App.router.send('next');
   },

+ 4 - 0
ambari-web/app/controllers/wizard/step9_controller.js

@@ -43,6 +43,10 @@ App.WizardStep9Controller = Em.Controller.extend({
     }
   }.property('hosts.@each.status'),
 
+  showRetry: function(){
+    return this.get('status') == 'failed';
+  }.property('status'),
+
   navigateStep: function () {
     if (this.get('content.cluster.isCompleted') === false) {
       this.loadStep();

+ 2 - 13
ambari-web/app/data/config_properties.js

@@ -1874,6 +1874,7 @@ module.exports =
       "serviceName": "OOZIE",
       "category": "Oozie Server"
     },
+    /*
     {
       "id": "puppet var",
       "name": "oozie_database",
@@ -1947,7 +1948,6 @@ module.exports =
       "serviceName": "OOZIE",
       "category": "Oozie Server"
     },
-
     {
       "id": "puppet var",
       "name": "oozie_database_name",
@@ -1984,6 +1984,7 @@ module.exports =
       "serviceName": "OOZIE",
       "category": "Oozie Server"
     },
+    */
     {
       "id": "puppet var",
       "name": "oozie_data_dir",
@@ -2021,18 +2022,6 @@ module.exports =
       "serviceName": "OOZIE",
       "category": "Advanced"
     },
-    /*{
-      "id": "puppet var",
-      "name": "oozie-site.xml",
-      "displayName": "Custom Oozie Configs",
-      "description": "If you wish to set configuration parameters not exposed through this page, you can specify them here.<br>The text you specify here will be injected into oozie-site.xml verbatim.",
-      "defaultValue": "",
-      "isRequired": false,
-      "displayType": "custom",
-      "isVisible": true,
-      "serviceName": "OOZIE",
-      "category": "Advanced"
-    },*/
     {
       "id": "puppet var",
       "name": "zookeeperserver_hosts",

+ 5 - 4
ambari-web/app/data/review_configs.js

@@ -114,11 +114,12 @@ module.exports = [
           Ember.Object.create({
             display_name: 'Server',
             component_value: ''
-          }),
-          Ember.Object.create({
-            display_name: 'Database',
-            component_value: ''
           })
+          // TODO: uncomment when ready to integrate with database other than Derby
+          // Ember.Object.create({
+          //   display_name: 'Database',
+          //   component_value: ''
+          // })
         ]
       }),
       Ember.Object.create({

+ 3 - 2
ambari-web/app/mappers/hosts_mapper.js

@@ -39,7 +39,9 @@ App.hostsMapper = App.QuickDataMapper.create({
     disk_info: 'Hosts.disk_info',
     $disk_usage: '-',
     health_status: 'Hosts.host_status',
-    $load_avg: '-',
+    load_one: 'Hosts.load.load_one',
+    load_five: 'Hosts.load.load_five',
+    load_fifteen: 'Hosts.load.load_fifteen',
     $cpu_usage: 33,
     $memory_usage: 26,
     $network_usage: 36,
@@ -53,7 +55,6 @@ App.hostsMapper = App.QuickDataMapper.create({
     if (!this.get('model')) {
       return;
     }
-
     if (json.items) {
       var result = [];
 

+ 1 - 1
ambari-web/app/mappers/users_mapper.js

@@ -22,6 +22,6 @@ App.usersMapper = App.QuickDataMapper.create({
   config : {
     user_name : 'Users.user_name',
     roles : 'Users.roles',
-    type: 'Users.type'
+    is_ldap: 'Users.ldap_user'
   }
 });

+ 3 - 1
ambari-web/app/messages.js

@@ -231,6 +231,7 @@ Em.I18n.translations = {
   'services.service.summary.averageLoad':'Average Load',
   'services.service.summary.masterHeap':'Master Heap',
   'services.service.summary.moreStats':'more stats here',
+  'services.service.summary.clientCount': '{0} Client Hosts',
   'services.service.actions.run.rebalancer':'Run Rebalancer',
   'services.service.actions.run.compaction':'Run Compaction',
   'services.service.actions.run.smoke':'Run Smoke Test',
@@ -351,5 +352,6 @@ Em.I18n.translations = {
   'timeRange.presets.1month':'1mo',
   'timeRange.presets.1year':'1yr',
 
-  'apps.filters.customRunDate':'Run Date custom filter'
+  'apps.filters.customRunDate':'Run Date custom filter',
+  'apps.dagCharts.popup':'DAG/Charts'
 };

+ 10 - 1
ambari-web/app/models/host.js

@@ -28,7 +28,6 @@ App.Host = DS.Model.extend({
   cpu: DS.attr('string'),
   memory: DS.attr('string'),
   diskUsage: DS.attr('string'),
-  loadAvg: DS.attr('string'),
   osArch: DS.attr('string'),
   ip: DS.attr('string'),
   rack: DS.attr('string'),
@@ -40,6 +39,9 @@ App.Host = DS.Model.extend({
   lastHeartBeatTime: DS.attr('number'),
   osType: DS.attr("string"),
   diskInfo: DS.attr('string'),
+  loadOne:DS.attr('number'),
+  loadFive:DS.attr('number'),
+  loadFifteen:DS.attr('number'),
 
 
   /**
@@ -55,6 +57,13 @@ App.Host = DS.Model.extend({
     return ((new Date()).getTime() - this.get('lastHeartBeatTime')) > 180 * 1000;
   }.property('lastHeartBeatTime'),
 
+  loadAvg: function() {
+    console.log(this.get('loadOne'), this.get('loadFive'), this.get('loadFifteen'));
+    if (this.get('loadOne') != null) return this.get('loadOne');
+    if (this.get('loadFive') != null) return this.get('loadFive');
+    if (this.get('loadFifteen') != null) return this.get('loadFifteen');
+  }.property('loadOne', 'loadFive', 'loadFifteen'),
+
   updateHostStatus: function(){
 
     /**

+ 3 - 1
ambari-web/app/models/host_component.js

@@ -23,7 +23,9 @@ App.HostComponent = DS.Model.extend({
   componentName: DS.attr('string'),
   host: DS.belongsTo('App.Host'),
   service: DS.belongsTo('App.Service'),
-
+  isClient:function () {
+    return Boolean(this.get('componentName').match(/_client/gi));
+  }.property('componentName'),
   isRunning: function(){
     return (this.get('workStatus') == 'STARTED' || this.get('workStatus') == 'STARTING');
   }.property('workStatus'),

+ 31 - 1
ambari-web/app/models/service.js

@@ -55,7 +55,37 @@ App.Service = DS.Model.extend({
     var components = this.get('components').filterProperty('isMaster', true);
     return components.everyProperty('workStatus', App.Component.Status.started);
   }.property('components.@each.workStatus'),
-
+  isMaintained: function(){
+    var maintainedServices = [
+      "HDFS",
+      "MAPREDUCE",
+      "HBASE",
+      "OOZIE",
+      "HIVE",
+      "ZOOKEEPER",
+      "PIG",
+      "SQOOP"
+    ];
+    for(var i in maintainedServices){
+      if(this.get('serviceName') == maintainedServices[i]) return true;
+    }
+  }.property('serviceName'),
+  isConfigurable:function(){
+    var configurableServices = [
+      "HDFS",
+      "MAPREDUCE",
+      "HBASE",
+      "OOZIE",
+      "HIVE",
+      "ZOOKEEPER",
+      "PIG",
+      "SQOOP",
+      "NAGIOS"
+    ];
+    for(var i in configurableServices){
+      if(this.get('serviceName') == configurableServices[i]) return true;
+    }
+  }.property('serviceName'),
   displayName: function () {
     switch (this.get('serviceName').toLowerCase()) {
       case 'hdfs':

+ 9 - 2
ambari-web/app/models/user.js

@@ -27,7 +27,13 @@ App.UserModel = Em.Object.extend({
 App.User = DS.Model.extend({
   userName:DS.attr('string'),
   roles:DS.attr('string'),
-  type:DS.attr('string'),
+  isLdap:DS.attr('boolean'),
+  type: function(){
+    if(this.get('isLdap')){
+      return 'LDAP';
+    }
+    return 'Local';
+  }.property('isLdap'),
   auditItems:DS.hasMany('App.ServiceAudit'),
   admin:function () {
     return !!(/^admin/.test(this.get('roles')))
@@ -45,7 +51,8 @@ App.EditUserForm = App.Form.extend({
     { name:"old_password", displayName:"Old Password", displayType:"password", isRequired: function(){ return this.get('form.isObjectNew'); }.property('form.isObjectNew') },
     { name:"new_password", displayName:"New Password", displayType:"password",  isRequired: false },
     { name:"admin", displayName:"Admin", displayType:"checkbox", isRequired:false },
-    { name:"roles", displayName:"Role", isRequired:false, isHidden:true }
+    { name:"roles", displayName:"Role", isRequired:false, isHidden:true },
+    { name:"isLdap", displayName:"Type", isRequired:false, isHidden:true }
   ],
   fields:[],
   disableUsername:function () {

+ 5 - 2
ambari-web/app/routes/add_host_routes.js

@@ -209,8 +209,11 @@ module.exports = Em.Route.extend({
     retry: function(router,context) {
       var addHostController = router.get('addHostController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
-      addHostController.installServices();
-      wizardStep9Controller.navigateStep();
+      if (!wizardStep9Controller.get('isSubmitDisabled')) {
+        addHostController.installServices(true);
+        addHostController.setInfoForStep9();
+        wizardStep9Controller.navigateStep();
+      }
     },
     next: function (router) {
       var addHostController = router.get('addHostController');

+ 12 - 3
ambari-web/app/routes/add_service_routes.js

@@ -92,7 +92,7 @@ module.exports = Em.Route.extend({
     },
     back: function(router){
       var controller = router.get('addServiceController');
-      if(controller.get('content.masterComponentHosts').someProperty('isInstalled', false)){
+      if(!controller.get('content.missMasterStep')){
         router.transitionTo('step2');
       } else {
         router.transitionTo('step1');
@@ -123,7 +123,16 @@ module.exports = Em.Route.extend({
         controller.connectOutlet('wizardStep7', controller.get('content'));
       })
     },
-    back: Em.Router.transitionTo('step3'),
+    back: function(router){
+      var controller = router.get('addServiceController');
+      if(!controller.get('content.missSlavesStep')){
+        router.transitionTo('step3');
+      } else if(!controller.get('content.missMasterStep')) {
+        router.transitionTo('step2');
+      } else {
+        router.transitionTo('step1');
+      }
+    },
     next: function (router) {
       var addServiceController = router.get('addServiceController');
       var wizardStep7Controller = router.get('wizardStep7Controller');
@@ -169,7 +178,7 @@ module.exports = Em.Route.extend({
       var addServiceController = router.get('addServiceController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
       if (!wizardStep9Controller.get('isSubmitDisabled')) {
-        addServiceController.installServices();
+        addServiceController.installServices(true);
         addServiceController.setInfoForStep9();
         wizardStep9Controller.navigateStep();
       }

+ 1 - 1
ambari-web/app/routes/installer.js

@@ -271,7 +271,7 @@ module.exports = Em.Route.extend({
       var installerController = router.get('installerController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
       if (!wizardStep9Controller.get('isSubmitDisabled')) {
-        installerController.installServices();
+        installerController.installServices(true);
         installerController.setInfoForStep9();
         wizardStep9Controller.navigateStep();
       }

+ 5 - 1
ambari-web/app/routes/main.js

@@ -97,7 +97,7 @@ module.exports = Em.Route.extend({
 
     showDetails:function (router, event) {
       router.get('mainHostDetailsController').setBack(true);
-      router.transitionTo('hostDetails.summary', event.context)
+      router.transitionTo('hostDetails.index', event.context)
     },
 
     addHost:function (router) {
@@ -279,6 +279,9 @@ module.exports = Em.Route.extend({
     service:Em.Route.extend({
       route:'/:service_id',
       connectOutlets:function (router, service) {
+        if (service && service.get('id') == 'Clients') {
+          service = App.router.get('mainServiceController.additionalMenuItem');
+        }
         router.get('mainServiceController').connectOutlet('mainServiceItem', service);
         router.transitionTo('summary');
       },
@@ -289,6 +292,7 @@ module.exports = Em.Route.extend({
         route:'/summary',
         connectOutlets:function (router, context) {
           var item = router.get('mainServiceItemController.content');
+          var viewName = 'mainServiceInfoSummary';
           router.get('mainServiceItemController').connectOutlet('mainServiceInfoSummary', item);
         }
       }),

+ 8 - 1
ambari-web/app/styles/application.less

@@ -643,6 +643,12 @@ a:focus {
   margin-top: 4px;
 }
 
+.modal-graph-line {
+  .modal-body {
+    min-height: 320px !important;
+  }
+}
+
 /*end alerts summary*/
 
 /*start chart/style graphs*/
@@ -1499,7 +1505,8 @@ ul.filter {
   }
   
   h4{
-    color: #777;
+    color: #777777;
+    margin-top: 5px;
   }
 }
 

+ 124 - 0
ambari-web/app/styles/apps.less

@@ -214,3 +214,127 @@
   -moz-border-radius: 4px;
 }
 
+/*Big modal window*/
+.big-modal {
+  .modal {
+    width: 1150px;
+    margin: -350px 0 0 -575px;
+  }
+
+  .clear {
+    clear:both;
+  }
+  > div > .dataTable {
+    border: 1px solid silver;
+    th {
+      border-top:none;
+    }
+  }
+  .content {
+    padding: 0;
+  }
+
+  .page-bar {
+    border: 1px solid silver;
+    text-align:right;
+    div {
+      display: inline-block;
+      margin:0 10px;
+    }
+    .dataTables_length {
+      label {
+        display:inline;
+      }
+      select {
+        margin-bottom: 4px;
+        margin-top: 4px;
+        width:70px;
+      }
+    }
+    .dataTables_paginate {
+      a {
+        padding:0 5px;
+      }
+    }
+  }
+
+  #graph1 {
+    margin-left: 30px;
+    width: 440px;
+    #legend_container {
+      margin: 40px 0 0 20px;
+    }
+  }
+
+  #graph2 {
+    margin-right: 30px;
+    width: 500px;
+    #tasks_legend_container {
+      margin: 40px 0 0 20px;
+    }
+  }
+
+  ul.nav-tabs{
+    margin-bottom: 0;
+  }
+
+  #jobs, #bars{
+    border: 1px solid #ddd;
+    border-top: none;
+    background: #fff;
+    padding: 10px;
+    box-sizing: border-box;
+    width: auto;
+  }
+
+  #jobs h2{
+    margin-top: 0;
+  }
+//fix stripped in inner table
+  .table-striped tbody tr:nth-child(odd)
+  td .table-striped tbody
+  tr:nth-child(odd) td,
+  tr:nth-child(even) th{
+    background-color: none;
+  }
+
+  .sorting_asc { background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAEwATAwERAAIRAQMRAf/EAHgAAAMBAQAAAAAAAAAAAAAAAAAFCAYKAQACAQUAAAAAAAAAAAAAAAAABQMCBAYHCBAAAQUAAQMEAwAAAAAAAAAAAwECBAUGABESByExIghBMxQRAAIBAwMDAwUAAAAAAAAAAAECAwAEBRESBiExUUHhB2GBIhMU/9oADAMBAAIRAxEAPwDvA8k+Qc54sxGj32qlNi0ucrjTj/JqGlmROyJXQ2u/bOsZTmBExPd70/HXmQcW41lOX5+145h0L391KEHhR3Z28Ii6sx9AKgubiO1gaeU6Io19h9TUg/S/7eP+wia3NbBIFbuqiyn3VTCjIMArHHTJarEDGGiNU8vOKVsc7/VxBuGR3yV683X86/Cq/GpssrhP2S8emiSKRm1JS5VfyLH0WfQug7KwZR0CilWHy39++ObQTgkgeV9ux+xq9uc6U8pLfZzP6mClZpKWrvq1DilJAt4Mewh/0hRyBOsaUMoVKLvXtVU6t6+nL/HZTJYi4/rxU81tdbSu+N2Rtp7jcpB0OnUa9aoeOOVdsgDL4I1pFS+NPHmcsQ2+fw+UpLWOwwwWNVQ1kCaIcgaiONkmLGEZrDDXtcnXo5PfjC+5VybKWrWWSyF5cWbEEpJNI6kqdQSrMRqD1B9KjS2t423xoqt5AArb8QVPRwoo4UUcKK//2Q==) no-repeat 85% 50%; }
+  .sorting_desc { background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAEwATAwERAAIRAQMRAf/EAIEAAAIDAQAAAAAAAAAAAAAAAAAGBwgJCgEBAAIDAQAAAAAAAAAAAAAAAAMFBAYHCBAAAAUDAwMFAAAAAAAAAAAAAQIDBAUABgcSNTYRFQgTZFUWZhEAAAQEAggGAwAAAAAAAAAAAAECAxEhBAYSMjFBYRMzFDQFUZFSYmMHJFRk/9oADAMBAAIRAxEAPwDv4oAKACgCKc1tMmusb3Eph6cSgsgx7fucEZxGRks2llGIGVWgVm8q1dt0+6ogKaapSgdNbQPXTqAdwsN602bopk3vTnUW24rduwccbU2S5E8Sm1JM92czSZwNOKUYDFrCqTp1corDUFMpEcYap+Ipb4P5O8n81y9xXXlG50yY+thR3AEivqFvRDmduvSUrhuLtrFNXqCFvJm1LAQ5RMuchB6gBy13f7+tP6lsOipuz2jSGdy1ZJeNzmXnEtU+pWFTikmbxyTEjgglKKZpMU3ZanudYtTtSr8dMoYSKKvKMte0aUV5YGxgoASbD2iQ4Tyi6uB7Rvz/AHD9R8r7/wBWr64uta6/pKfq+JwUZP5/1/hwCFjIeTMrLo0np93q2xDtVCJh/9k=) no-repeat 85% 50%; }
+  .sorting { background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAEwATAwERAAIRAQMRAf/EAGgAAAIDAQAAAAAAAAAAAAAAAAUHAAYICgEBAQAAAAAAAAAAAAAAAAAAAAEQAAEEAQIFAgcAAAAAAAAAAAECAwQFABEGIRI0NQcTFDFBMmNUZRYRAQEBAQAAAAAAAAAAAAAAAAABEUH/2gAMAwEAAhEDEQA/AO93cd/XbXpLC9tHQ1Dr46nljUBby/gzGZB+p+Q6QhA+ZOApfDnllW/ha1tv6Ee7iyH5kRlvlbTIqHndWkNJ0HO7XFQbWeJUkpUeOpySrZh65UUnyFUW1ztaexRmIbaPyzoLE6vg2UWW9GC1e0XHnsSGEqfQohCwApK9OIGuAjfBP9VuG0m39vGqINVUe4r2xF21TVsuXZOI9N9lMmLBYkttQ21auBKhqtSUngCMkW5xqjKiYASh6SR2Tulr2HpOvf6j9p+V9/mwDeB//9k=) no-repeat 85% 50%; }
+
+  a.paginate_disabled_next, a.paginate_disabled_previous {
+    color: gray;
+    &:hover {
+      color: gray;
+      text-decoration: none;
+    }
+  }
+
+  a.paginate_enabled_next, a.paginate_enabled_previous {
+    &:hover {
+      text-decoration: none;
+    }
+  }
+
+  div.view-wrapper {
+    float: left;
+  }
+
+  a.ui-icon-circle-close {
+    float: right;
+    opacity: 0.2;
+    padding: 1px;
+    position: relative;
+    top: -32px;
+    &:hover {
+      opacity: 0.7;
+    }
+  }
+  .notActive {
+    a.ui-icon-circle-close {
+      visibility: hidden;
+    }
+  }
+}
+
+/*Big modal window end*/

+ 3 - 0
ambari-web/app/templates/main/charts/heatmap/heatmap_rack.hbs

@@ -44,8 +44,11 @@
 <!--</div>-->
 <div {{bindAttr class="view.heatmapTogglerClass view.hostsBlockClass"}}>
   {{#each rack.hosts}}
+  <a href="#" {{action "routeHostDetail" this target="controller"}}>
     <div {{bindAttr style="view.hostCssStyle"}}>
       {{view App.MainChartsHeatmapHostView contentBinding="this"}}
     </div>
+  </a>
   {{/each}}
+
 </div>

+ 1 - 1
ambari-web/app/templates/main/charts/linear_time.hbs

@@ -15,7 +15,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
-<div id="{{unbound view.id}}-container" class="chart-container">
+<div id="{{unbound view.id}}-container" class="chart-container" {{action showGraphInPopup target="view"}}>
   <div id="{{unbound view.id}}-yaxis" class="chart-y-axis"></div>
   <div id="{{unbound view.id}}-xaxis" class="chart-x-axis"></div>
   <div id="{{unbound view.id}}-legend" class="chart-legend"></div>

+ 0 - 55
ambari-web/app/templates/main/dashboard.hbs

@@ -60,60 +60,5 @@
 				</div>
 			</div>
 		</div>
-    <div class="box alerts-section">
-      <div class="box-header">
-        <h4>Alerts</h4>
-        <div class="btn-group">
-          <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">{{controller.alertsFilteredByName}} <span class="caret"></span></button>
-          <a class="btn" target="_blank" rel="tooltip" title="Go to Nagios" {{bindAttr href="controller.nagiosUrl"}}><i class="icon-link"></i></a>
-          <ul class="dropdown-menu">
-            <li><a {{action alertsFilter target="controller"}} href="javascript:void(null)">All</a></li>
-            {{#each service in view.content}}
-              <li><a {{action alertsFilter service target="controller"}} href="javascript:void(null)">{{service.model.displayName}}</a></li>
-            {{/each}}
-          </ul>
-        </div>
-      </div>
-      <ul class="alerts">
-        {{#if controller.displayAlerts.length}}
-	        {{#each controller.displayAlerts}}
-		        <li class="status-{{unbound status}}">
-		          <div class="container-fluid">
-		            <div class="row-fluid">
-		              <div class="span1 status-icon">
-		                {{#if isOk}}
-		                  <i class="icon-ok icon-large"></i>
-		                {{else}}
-		                  <i class="icon-remove icon-large"></i>
-		                {{/if}}
-		              </div>
-		              <div class="span11">
-		                <div class="row-fluid">
-		                  <div class="span8 title">{{title}}
-		                    {{#if serviceLink}}
-		                      <a class="serviceLink" href="{{unbound serviceLink}}">{{serviceName}}</a>
-		                    {{/if}}
-		                  </div>
-		                  <div class="span4 date-time">{{dateDisplay}}</div>
-		                </div>
-		                <div class="row-fluid message">{{message}}</div>
-		              </div>
-		            </div>
-		          </div>
-		        </li>
-	        {{/each}}
-	      {{else}}
-	        {{#if controller.isNagiosInstalled}}
-	          <div class="alert alert-info">
-	            No alerts
-	          </div>
-	        {{else}}
-	          <div class="alert">
-	            Nagios service required for viewing alerts
-	          </div>
-	        {{/if}}
-	      {{/if}}
-      </ul>
-    </div>
 	</div>
 </div>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hbase.hbs

@@ -22,7 +22,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-    <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hdfs.hbs

@@ -22,7 +22,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-    <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hive.hbs

@@ -21,7 +21,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-    <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/mapreduce.hbs

@@ -22,7 +22,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-      <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/oozie.hbs

@@ -21,7 +21,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-    <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/zookeeper.hbs

@@ -21,7 +21,7 @@
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
-    <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
+      <a {{action selectService view.service href=true}} class="label label-important">{{view.criticalAlertsCount}}</a>
     {{/if}}
   </div>
   <div class="summary span">

+ 1 - 1
ambari-web/app/templates/main/host.hbs

@@ -41,7 +41,7 @@
       <th class="notActive"><div class="view-wrapper">{{view view.cpuFilterView viewName="cpuFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_cpuFilterViewInstance" class="ui-icon ui-icon-circle-close ui-cpu"></a></th>
       <th class="notActive"><div class="view-wrapper">{{view view.ramFilterView viewName="ramFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_ramFilterViewInstance" class="ui-icon ui-icon-circle-close ui-ram"></a></th>
       <th></th>
-      <th></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.loadAvgFilterView viewName="loadAvgFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_loadAvgFilterViewInstance" class="ui-icon ui-icon-circle-close ui-load_avg"></a></th>
       <th class="notActive"><input id="components_filter" type="hidden" />
           <div class="view-wrapper">{{view view.componentsFilterView viewName="componentsFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_componentsFilterViewInstance" class="ui-icon ui-icon-circle-close ui-components"></a>
       </th>

+ 111 - 0
ambari-web/app/templates/main/service/info/client_summary.hbs

@@ -0,0 +1,111 @@
+{{!
+* 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.
+}}
+
+<div class="row-fluid service-block">
+  <div class="span6">
+    {{#if view.service.quickLinks.length}}
+    {{#view App.QuickViewLinks contentBinding="view.service"}}
+    <ul class="nav nav-pills move">
+      <li class="dropdown">
+        <a class="dropdown-toggle" data-toggle="dropdown" href="#">Quick Links <b class="caret"></b></a>
+        <ul class="dropdown-menu">
+          {{#each view.quickLinks}}
+          <a {{bindAttr href="url"}}>{{label}}</a>
+          {{/each}}
+        </ul>
+      </li>
+    </ul>
+    {{/view}}
+    {{/if}}
+
+    <div class="box">
+      <div class="box-header">
+        <h4>{{controller.content.label}} Summary</h4>
+      </div>
+      <div class="service-content">
+        <table id="summary-info" class="table table-bordered table-striped table-condensed">
+          <tbody>
+
+          {{#if controller.content.isClients}}
+          <tr>
+            <td class="summary-label">Client Hosts</td>
+            <td>{{view.clientHostsLength}}</td>
+          </tr>
+          {{#if view.clientComponentsString}}
+          <tr>
+            <td style="text-align: left;" colspan="2">
+              {{view.clientComponentsString}}
+            </td>
+          </tr>
+          {{/if}}
+          {{/if}}
+          </tbody>
+        </table>
+      </div>
+    </div>
+  </div>
+  <div class="span6">
+    <div class="box">
+      <div class="box-header">
+        <h4>Alerts</h4>
+
+        <div class="btn-group">
+          <a class="btn" target="_blank" rel="tooltip" title="Go to Nagios" {{bindAttr href="controller.nagiosUrl"}}><i
+              class="icon-link"></i></a>
+        </div>
+      </div>
+      <ul id='summary-alerts-list' class="alerts">
+        {{#if controller.alerts.length}}
+        {{#each controller.alerts}}
+        <li class="status-{{unbound status}}">
+          <div class="container-fluid">
+            <div class="row-fluid">
+              <div class="span1 status-icon">
+                {{#if isOk}}
+                <i class="icon-ok icon-large"></i>
+                {{else}}
+                <i class="icon-remove icon-large"></i>
+                {{/if}}
+              </div>
+              <div class="span11">
+                <div class="row-fluid">
+                  <div class="span7 title">{{title}}
+                  </div>
+                  <div class="span5 date-time">{{dateDisplay}}</div>
+                </div>
+                <div class="row-fluid message">{{message}}</div>
+              </div>
+            </div>
+          </div>
+        </li>
+        {{/each}}
+        {{else}}
+        {{#if controller.isNagiosInstalled}}
+        <div class="alert alert-info">
+          No alerts
+        </div>
+        {{else}}
+        <div class="alert">
+          Nagios service required for viewing alerts
+        </div>
+        {{/if}}
+        {{/if}}
+      </ul>
+    </div>
+  </div>
+</div>

+ 5 - 1
ambari-web/app/templates/main/service/item.hbs

@@ -16,8 +16,10 @@
 * limitations under the License.
 }}
 
-{{view App.MainServiceInfoMenuView}}
+{{view App.MainServiceInfoMenuView configTabBinding="view.hasConfigTab"}}
+{{#unless controller.content.isClients}}
 <div class="service-button">
+  {{#if view.hasMaintenanceControl}}
   <div class="btn-group display-inline-block">
     <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
       {{t services.service.actions.maintenance}}
@@ -32,6 +34,7 @@
       {{/each}}
     </ul>
   </div>
+  {{/if}}
   <a href="javascript:void(null)" {{bindAttr class=":btn controller.content.isRunning:disabled:btn-success" }}
      data-toggle="modal" {{action "startService" target="controller"}}>
     <i class="icon-play"></i>
@@ -43,4 +46,5 @@
     Stop
   </a>
 </div>
+{{/unless}}
 {{outlet}}

+ 5 - 1
ambari-web/app/templates/main/service/menu_item.hbs

@@ -17,7 +17,11 @@
 }}
 
 <a href="#/main/services/{{unbound view.content.id}}/summary">
-  {{view App.MainDashboardServiceHealthView class="service-health" serviceBinding="view.content"}}&nbsp;<span>{{unbound view.content.displayName}}</span>
+  {{#if view.content.isClients}}
+  {{else}}
+  {{view App.MainDashboardServiceHealthView class="service-health" serviceBinding="view.content"}}&nbsp;
+  {{/if}}
+  <span>{{unbound view.content.displayName}}</span>
   {{#if view.alertsCount}}
     <span class="label operations-count">
       {{view.alertsCount}}

+ 1 - 1
ambari-web/app/templates/wizard/step7.hbs

@@ -121,7 +121,7 @@
   {{/if}}
 
   <div class="btn-area">
-    <a class="btn" {{action back href="true"}}>&larr; Back</a>
+    <a class="btn" {{action back}}>&larr; Back</a>
 
     <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
       {{action submit target="controller"}}>Next &rarr;</a>

+ 2 - 0
ambari-web/app/templates/wizard/step9.hbs

@@ -39,10 +39,12 @@
   <div class="box">
     <div class="box-header">
       <div class="pull-left">
+        {{#if controller.showRetry}}
         <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
            href="#" {{action retry}}><i class="icon-repeat icon-white"></i>
           Retry
         </a>
+        {{/if}}
         {{#if App.testMode}}
         <a class="btn btn-info" href="#" {{action mockBtn target="controller"}}>
           mockData

+ 3 - 2
ambari-web/app/utils/data_table.js

@@ -20,7 +20,7 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
 
   "num-html-pre": function(date_string) {
     date_string = $(date_string).text();
-    return parseInt(date_string, 10);
+    return parseFloat(date_string, 10);
   },
 
   "num-html-asc": function (a, b) {
@@ -156,6 +156,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
       var inputFilters = [
         {iColumn: '0', elementId: 'star_filter', type: 'star'},
         {iColumn: '2', elementId: 'cpu_filter', type: 'number'},
+        {iColumn: '5', elementId: 'load_avg_filter', type: 'number'},
         {iColumn: '4', elementId: 'user_filter', type: 'multiple'},
         {iColumn: '6', elementId: 'components_filter', type: 'multiple'},
         {iColumn: '5', elementId: 'jobs_filter', type: 'number' },
@@ -350,7 +351,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
 
       function numberFilter(rangeExp, rowValue) {
         var compareChar = rangeExp.charAt(0);
-        var compareValue = parseInt(rangeExp.substr(1, rangeExp.length - 1));
+        var compareValue = parseFloat(rangeExp.substr(1, rangeExp.length - 1));
         rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
         match = false;
         switch (compareChar) {

+ 88 - 33
ambari-web/app/views/common/chart/linear_time.js

@@ -81,6 +81,10 @@ App.ChartLinearTimeView = Ember.View.extend({
        */
       _graph: null,
 
+      popupSuffix: '-popup',
+
+      isPopup: false,
+
       /**
        * Color palette used for this chart
        * 
@@ -103,6 +107,10 @@ App.ChartLinearTimeView = Ember.View.extend({
 
       didInsertElement: function () {
         this._super();
+        this.loadData();
+      },
+
+      loadData: function() {
         var validUrl = this.get('url');
         if (validUrl) {
           var hash = {};
@@ -129,6 +137,9 @@ App.ChartLinearTimeView = Ember.View.extend({
        */
       _showMessage: function(type, title, message){
         var chartOverlayId = '#' + this.id + '-chart';
+        if (this.get('isPopup')) {
+          chartOverlayId += this.get('popupSuffix');
+        }
         var typeClass;
         switch (type) {
           case 'error':
@@ -209,6 +220,41 @@ App.ChartLinearTimeView = Ember.View.extend({
       _refreshGraph: function (jsonData) {
         var seriesData = this.transformToSeries(jsonData);
         if (seriesData instanceof Array && seriesData.length>0) {
+            this.draw(seriesData);
+        }
+        else {
+          this._showMessage('info', 'No Data', 'There was no data available.');
+        }
+      },
+
+      /**
+       * @private
+       * 
+       * When a graph is given a particular width and height,the lines are drawn
+       * in a slightly bigger area thereby chopping off some of the UI. Hence
+       * after the rendering, we adjust the SVGs size in the DOM to compensate.
+       * 
+       * Opened https://github.com/shutterstock/rickshaw/issues/141
+       * 
+       * @type Function
+       */
+      _adjustSVGHeight: function () {
+        if (this._graph && this._graph.element
+            && this._graph.element.firstChild) {
+          var svgElement = this._graph.element.firstChild;
+          svgElement.setAttribute('height', $(this._graph.element).height()
+              + "px");
+          svgElement.setAttribute('width', $(this._graph.element).width()
+              + "px");
+        }
+      },
+
+      draw: function(seriesData) {
+          var isPopup = this.get('isPopup');
+          var p = '';
+          if (isPopup) {
+            p = this.get('popupSuffix');
+          }
           var palette = new Rickshaw.Color.Palette({
             scheme: this._paletteScheme
           });
@@ -216,19 +262,17 @@ App.ChartLinearTimeView = Ember.View.extend({
             series.color = this.colorForSeries(series) || palette.color();
             series.stroke = 'rgba(0,0,0,0.3)';
           }.bind(this));
-          
-          if (this._graph == null) {
-            var chartId = "#" + this.id + "-chart";
-            var chartOverlayId = "#" + this.id + "-overlay";
-            var xaxisElementId = "#" + this.id + "-xaxis";
-            var yaxisElementId = "#" + this.id + "-yaxis";
-            var legendElementId = "#" + this.id + "-legend";
+            var chartId = "#" + this.id + "-chart" + p;
+            var chartOverlayId = "#" + this.id + "-overlay" + p;
+            var xaxisElementId = "#" + this.id + "-xaxis" + p;
+            var yaxisElementId = "#" + this.id + "-yaxis" + p;
+            var legendElementId = "#" + this.id + "-legend" + p;
+
             var chartElement = document.querySelector(chartId);
             var overlayElement = document.querySelector(chartOverlayId);
             var xaxisElement = document.querySelector(xaxisElementId);
             var yaxisElement = document.querySelector(yaxisElementId);
             var legendElement = document.querySelector(legendElementId);
-
             this._graph = new Rickshaw.Graph({
               height: 150,
               element: chartElement,
@@ -276,33 +320,44 @@ App.ChartLinearTimeView = Ember.View.extend({
             // this._graph.onUpdate(jQuery.proxy(function () {
             // this._adjustSVGHeight();
             // }, this));
-          }
-          this._graph.render();
-        }else{
-          this._showMessage('info', 'No Data', 'There was no data available.');
-        }
+
+        this._graph.render();
+        this._graph = null;
+        this.set('isPopup', false);
       },
 
-      /**
-       * @private
-       * 
-       * When a graph is given a particular width and height,the lines are drawn
-       * in a slightly bigger area thereby chopping off some of the UI. Hence
-       * after the rendering, we adjust the SVGs size in the DOM to compensate.
-       * 
-       * Opened https://github.com/shutterstock/rickshaw/issues/141
-       * 
-       * @type Function
-       */
-      _adjustSVGHeight: function () {
-        if (this._graph && this._graph.element
-            && this._graph.element.firstChild) {
-          var svgElement = this._graph.element.firstChild;
-          svgElement.setAttribute('height', $(this._graph.element).height()
-              + "px");
-          svgElement.setAttribute('width', $(this._graph.element).width()
-              + "px");
-        }
+      showGraphInPopup: function() {
+        this.set('isPopup', true);
+        App.ModalPopup.show({
+          template: Ember.Handlebars.compile([
+            '<div class="modal-backdrop"></div><div class="modal modal-graph-line" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">',
+            '<div class="modal-header">',
+            '<a class="close" {{action onClose target="view"}}>x</a>',
+            '<h3 id="modal-label">',
+            '{{#if headerClass}}{{view headerClass}}',
+            '{{else}}{{header}}{{/if}}',
+            '</h3>',
+            '</div>',
+            '<div class="modal-body">',
+            '{{#if bodyClass}}{{view bodyClass}}',
+            '{{else}}<div id="'+this.get('id')+'-container'+this.get('popupSuffix')+'" class="chart-container"><div id="'+this.get('id')+'-yaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-yaxis chart-y-axis"></div><div id="'+this.get('id')+'-xaxis'+this.get('popupSuffix')+'" class="'+this.get('id')+'-xaxis chart-x-axis"></div><div id="'+this.get('id')+'-legend'+this.get('popupSuffix')+'" class="'+this.get('id')+'-legend chart-legend"></div><div id="'+this.get('id')+'-overlay'+this.get('popupSuffix')+'" class="'+this.get('id')+'-overlay chart-overlay"></div><div id="'+this.get('id')+'-chart'+this.get('popupSuffix')+'" class="'+this.get('id')+'-chart chart"></div><div id="'+this.get('id')+'-title'+this.get('popupSuffix')+'" class="'+this.get('id')+'-title chart-title">{{view.title}}</div></div>{{/if}}',
+            '</div>',
+            '<div class="modal-footer">',
+            '{{#if view.primary}}<a class="btn btn-success" {{action onPrimary target="view"}}>{{view.primary}}</a>{{/if}}',
+            '</div>',
+            '</div>'
+          ].join('\n')),
+
+          header: this.get('title'),
+          primary: 'OK',
+          onPrimary: function() {
+            this.hide();
+          }
+        });
+        var self = this;
+        Ember.run.next(function() {
+          self.loadData();
+        });
       }
     });
 

+ 11 - 1
ambari-web/app/views/main/admin/user/edit.js

@@ -58,6 +58,16 @@ App.MainAdminUserEditView = Em.View.extend({
   userForm: App.EditUserForm.create({}),
 
   didInsertElement: function(){
-    this.get('userForm').propertyDidChange('object');
+    var form = this.get('userForm');
+    if( form.getField("isLdap").get("value") )
+    {
+      form.getField("old_password").set("disabled",true);
+      form.getField("new_password").set("disabled",true);
+    }else{
+      //debugger;
+      form.getField("old_password").set("disabled",false);
+      form.getField("new_password").set("disabled",false);
+    }
+    form.propertyDidChange('object');
   }
 });

+ 15 - 42
ambari-web/app/views/main/apps_view.js

@@ -823,13 +823,7 @@ App.MainAppsView = Em.View.extend({
       }
     }
   }),
-  /**
-   *  Object contain views of expanded row
-   */
-  expandedRow:Ember.Object.create({
-    rowView:null,
-    rowChildView:null
-  }),
+
   /**
    * This Container View is used to render static table row(appTableRow) and additional dynamic content
    */
@@ -841,44 +835,23 @@ App.MainAppsView = Em.View.extend({
     id: function() {
       return this.get('run.id');
     }.property("run.id"),
-    /**
-     * Delete expanded row from table
-     *
-     * @param row
-     */
-    deleteRow:function(row){
-      row.get('rowChildView').destroy();
-      row.get('rowView').set('expanded', false);
-      row.set('rowView', null);
-      row.set('rowChildView', null);
-    },
-    viewCreate:function(){
-      App.router.get('mainAppsItemController').set('content', this.get('run'));
-      var newView = App.MainAppsItemView.create({
-        controllerBinding: 'App.router.mainAppsItemController'
-      });
-      return newView;
-    },
-    expanded : false,
+
     /**
      * Show/hide additional content appropriated for this row
      */
     expandToggle : function(){
-      var newView;
-      var expandedView = this.get('parentView.expandedRow');
-      if(expandedView.get('rowView')) {
-        if(this.get('expanded')){
-          this.deleteRow(expandedView);
-          return;
-        }
-        this.deleteRow(expandedView);
-      }
-
-      newView = this.viewCreate();
-      this.set('expanded', true);
-      expandedView.set('rowView', this);
-      expandedView.set('rowChildView', newView);
-      this.get('childViews').pushObject(newView);
+      App.router.get('mainAppsItemController').set('content', this.get('run'));
+      App.ModalPopup.show({
+        classNames: ['big-modal'],
+        header: Em.I18n.t('apps.dagCharts.popup'),
+        bodyClass: App.MainAppsItemView.extend({
+          controllerBinding: 'App.router.mainAppsItemController'
+        }),
+        onPrimary: function() {
+          this.hide();
+        },
+        secondary : null
+      });
     }
   }),
   /**
@@ -900,4 +873,4 @@ App.MainAppsView = Em.View.extend({
 
   })
 
-});
+});

+ 1 - 1
ambari-web/app/views/main/dashboard/service.js

@@ -87,7 +87,7 @@ App.MainDashboardServiceView = Em.View.extend({
   }.property('controller.data'),
 
   criticalAlertsCount: function () {
-    var alerts = this.get('controller.alerts');
+    var alerts = App.router.get('clusterController.alerts');
     return alerts.filterProperty('serviceType', this.get('service.id')).filterProperty('status', '1').length;
   }.property('service.alerts')
 

+ 19 - 1
ambari-web/app/views/main/host.js

@@ -52,7 +52,7 @@ App.MainHostView = Em.View.extend({
         { "sType":"num-html" },
         { "sType":"ambari-bandwidth" },
         { "sType":"string" },
-        { "sType":"string" },
+        { "sType":"num-html" },
         { "sType":"string", "bSortable": false  }
       ]
     });
@@ -159,6 +159,24 @@ App.MainHostView = Em.View.extend({
       this.get('parentView').get('applyFilter')(this.get('parentView'), 2);
     }.observes('value')
   }),
+  /**
+   * Filter-field for load avg
+   */
+  loadAvgFilterView: Em.TextField.extend({
+    classNames:['input-mini'],
+    type:'text',
+    placeholder: 'Any ',
+    elementId:'load_avg_filter',
+    filtering:function(){
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
+      this.get('parentView').get('applyFilter')(this.get('parentView'), 2);
+    }.observes('value')
+  }),
   /**
    * Filter-field for RAM
    */

+ 8 - 5
ambari-web/app/views/main/service/info/menu.js

@@ -21,11 +21,14 @@ var App = require('app');
 App.MainServiceInfoMenuView = Em.CollectionView.extend({
   tagName: 'ul',
   classNames: ["nav", "nav-tabs"],
-  content:[
-    { label:'Summary', routing:'summary', active:"active"},
-    { label:'Configs', routing:'configs'}/*,
-    { label:'Audit', routing:'audit'}*/
-  ],
+  content:function(){
+    var menuItems = [
+      { label:'Summary', routing:'summary', active:"active"}
+      //{ label:'Audit', routing:'audit'}
+    ];
+    if(this.get('configTab')) menuItems.push({ label:'Configs', routing:'configs'});
+    return menuItems;
+  }.property(),
 
   init: function(){ this._super(); this.activateView(); },
 

+ 81 - 55
ambari-web/app/views/main/service/info/summary.js

@@ -5,9 +5,9 @@
  * 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
@@ -18,28 +18,31 @@
 var App = require('app');
 
 App.MainServiceInfoSummaryView = Em.View.extend({
-  templateName: require('templates/main/service/info/summary'),
-  attributes: null,
-  serviceStatus: {
-    hdfs: false,
-    mapreduce: false,
-    hbase: false,
-    zookeeper: false,
-    oozie: false,
-    hive: false
+  templateName:function () {
+    var service = this.get('controller.content');
+    return require(service.get('isClients') ? 'templates/main/service/info/client_summary' : 'templates/main/service/info/summary');
+  }.property('controller.content'),
+  attributes:null,
+  serviceStatus:{
+    hdfs:false,
+    mapreduce:false,
+    hbase:false,
+    zookeeper:false,
+    oozie:false,
+    hive:false
   },
 
   data:{
     hive:{
-      "database"     : "PostgreSQL",
-      "databaseName" : "hive",
-      "user"         : "hive"
+      "database":"PostgreSQL",
+      "databaseName":"hive",
+      "user":"hive"
     }
   },
-  service: function () {
+  service:function () {
     var svc = this.get('controller.content');
     var svcName = svc.get('serviceName');
-    if(svcName){
+    if (svcName) {
       switch (svcName.toLowerCase()) {
         case 'hdfs':
           svc = App.HDFSService.find().objectAt(0);
@@ -57,60 +60,60 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return svc;
   }.property('controller.content'),
 
-  isHide: true,
-  moreStatsView: Em.View.extend({
-    tagName: "a",
-    template: Ember.Handlebars.compile('{{t services.service.summary.moreStats}}'),
-    attributeBindings: [ 'href' ],
-    classNames: [ 'more-stats' ],
-    click: function (event) {
+  isHide:true,
+  moreStatsView:Em.View.extend({
+    tagName:"a",
+    template:Ember.Handlebars.compile('{{t services.service.summary.moreStats}}'),
+    attributeBindings:[ 'href' ],
+    classNames:[ 'more-stats' ],
+    click:function (event) {
       this._parentView._parentView.set('isHide', false);
       this.remove();
     },
-    href: 'javascript:void(null)'
+    href:'javascript:void(null)'
   }),
 
-  serviceName: function () {
+  serviceName:function () {
     return this.get('service.serviceName');
   }.property('service'),
 
-  oldServiceName : '',
-  
+  oldServiceName:'',
+
   /**
    * Contains graphs for this particular service
    */
-  serviceMetricGraphs: function(){
+  serviceMetricGraphs:function () {
     var svcName = this.get('service.serviceName');
     var graphs = [];
-    if(svcName){
+    if (svcName) {
       switch (svcName.toLowerCase()) {
         case 'hdfs':
           graphs = [ App.ChartServiceMetricsHDFS_SpaceUtilization.extend(),
-                     App.ChartServiceMetricsHDFS_FileOperations.extend(), 
-                     App.ChartServiceMetricsHDFS_BlockStatus.extend(), 
-                     App.ChartServiceMetricsHDFS_IO.extend(), 
-                     App.ChartServiceMetricsHDFS_RPC.extend(), 
-                     App.ChartServiceMetricsHDFS_GC.extend(), 
-                     App.ChartServiceMetricsHDFS_JVMHeap.extend(), 
-                     App.ChartServiceMetricsHDFS_JVMThreads.extend()];
+            App.ChartServiceMetricsHDFS_FileOperations.extend(),
+            App.ChartServiceMetricsHDFS_BlockStatus.extend(),
+            App.ChartServiceMetricsHDFS_IO.extend(),
+            App.ChartServiceMetricsHDFS_RPC.extend(),
+            App.ChartServiceMetricsHDFS_GC.extend(),
+            App.ChartServiceMetricsHDFS_JVMHeap.extend(),
+            App.ChartServiceMetricsHDFS_JVMThreads.extend()];
           break;
         case 'mapreduce':
-          graphs = [ App.ChartServiceMetricsMapReduce_JobsStatus.extend(), 
-                     App.ChartServiceMetricsMapReduce_JobsRunningWaiting.extend(), 
-                     App.ChartServiceMetricsMapReduce_MapSlots.extend(), 
-                     App.ChartServiceMetricsMapReduce_ReduceSlots.extend(), 
-                     App.ChartServiceMetricsMapReduce_GC.extend(), 
-                     App.ChartServiceMetricsMapReduce_RPC.extend(), 
-                     App.ChartServiceMetricsMapReduce_JVMHeap.extend(), 
-                     App.ChartServiceMetricsMapReduce_JVMThreads.extend()];
+          graphs = [ App.ChartServiceMetricsMapReduce_JobsStatus.extend(),
+            App.ChartServiceMetricsMapReduce_JobsRunningWaiting.extend(),
+            App.ChartServiceMetricsMapReduce_MapSlots.extend(),
+            App.ChartServiceMetricsMapReduce_ReduceSlots.extend(),
+            App.ChartServiceMetricsMapReduce_GC.extend(),
+            App.ChartServiceMetricsMapReduce_RPC.extend(),
+            App.ChartServiceMetricsMapReduce_JVMHeap.extend(),
+            App.ChartServiceMetricsMapReduce_JVMThreads.extend()];
           break;
         case 'hbase':
           graphs = [  App.ChartServiceMetricsHBASE_ClusterRequests.extend(),
-                      App.ChartServiceMetricsHBASE_RegionServerReadWriteRequests.extend(),
-                      App.ChartServiceMetricsHBASE_RegionServerRegions.extend(),
-                      App.ChartServiceMetricsHBASE_RegionServerQueueSize.extend(),
-                      App.ChartServiceMetricsHBASE_HlogSplitTime.extend(),
-                      App.ChartServiceMetricsHBASE_HlogSplitSize.extend()];
+            App.ChartServiceMetricsHBASE_RegionServerReadWriteRequests.extend(),
+            App.ChartServiceMetricsHBASE_RegionServerRegions.extend(),
+            App.ChartServiceMetricsHBASE_RegionServerQueueSize.extend(),
+            App.ChartServiceMetricsHBASE_HlogSplitTime.extend(),
+            App.ChartServiceMetricsHBASE_HlogSplitSize.extend()];
           break;
         default:
           break;
@@ -119,14 +122,14 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return graphs;
   }.property('service'),
 
-  loadServiceSummary: function (serviceName) {
+  loadServiceSummary:function (serviceName) {
 
     var serviceName = this.get('serviceName');
-    if(!serviceName){
+    if (!serviceName) {
       return;
     }
 
-    if(this.get('oldServiceName')){
+    if (this.get('oldServiceName')) {
       // do not delete it!
       return;
     }
@@ -145,8 +148,8 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     this.set('oldServiceName', serviceName);
     serviceName = serviceName.toLowerCase();
   }.observes('serviceName'),
-  
-  didInsertElement: function () {
+
+  didInsertElement:function () {
     // We have to make the height of the Alerts section
     // match the height of the Summary section.
     var summaryTable = document.getElementById('summary-info');
@@ -160,5 +163,28 @@ App.MainServiceInfoSummaryView = Em.View.extend({
         $(summaryTable).attr('style', "height:" + alertsList.clientHeight + "px;");
       }
     }
-  }
+  },
+
+
+  clientHosts:App.Host.find(),
+
+  clientHostsLength:function () {
+    var text = this.t('services.service.summary.clientCount');
+    var self = this;
+    return text.format(self.get('clientHosts.length'));
+  }.property('clientHosts'),
+
+  clientComponents:function () {
+    return App.HostComponent.find().filterProperty('isClient', true);
+  }.property(),
+
+  clientComponentsString:function () {
+    var components = this.get('clientComponents');
+    var names = [];
+    components.forEach(function (component) {
+      names.push(component.get('displayName'));
+    });
+
+    return names.length ? names.join(', ') : false;
+  }.property('clientComponents')
 });

+ 11 - 4
ambari-web/app/views/main/service/item.js

@@ -24,16 +24,23 @@ App.MainServiceItemView = Em.View.extend({
     var options = [];
     var service = this.get('controller.content');
     switch(service.get('serviceName')) {
-      case 'hdfs':
+      case 'HDFS':
         options.push({action: 'runRebalancer', 'label': Em.I18n.t('services.service.actions.run.rebalancer')});
         break;
-      case 'hbase':
+      case 'HBASE':
         options.push({action: 'runCompaction', 'label': Em.I18n.t('services.service.actions.run.compaction')});
         break;
+      default:
+        options.push({action: 'runSmokeTest', 'label': Em.I18n.t('services.service.actions.run.smoke')});
     }
-    options.push({action: 'runSmokeTest', 'label': Em.I18n.t('services.service.actions.run.smoke')});
     return options;
-  }.property('controller.content')
+  }.property('controller.content'),
+  hasMaintenanceControl: function(){
+    return this.get("controller.content.isMaintained");
+  }.property('controller.content.isMaintained'),
+  hasConfigTab: function(){
+    return this.get("controller.content.isConfigurable");
+  }.property('controller.content.isConfigurable')
 });
 
 App.MainServiceItemOperations = Em.View.extend({

+ 12 - 1
ambari-web/app/views/main/service/menu.js

@@ -20,7 +20,18 @@ var App = require('app');
 
 App.MainServiceMenuView = Em.CollectionView.extend({
   content:function () {
-    return App.router.get('mainServiceController.content');
+    var items = App.router.get('mainServiceController.content').toArray();
+
+    var itemsToRemove = ['PIG', 'SQOOP'];
+
+    items.forEach(function (item) {
+      if (itemsToRemove.indexOf(item.get('serviceName')) != -1) {
+        items.removeObject(item);
+      }
+    });
+
+    items.push(App.router.get('mainServiceController.additionalMenuItem'));
+    return items;
   }.property('App.router.mainServiceController.content'),
 
 

+ 2 - 2
ambari-web/app/views/wizard/controls_view.js

@@ -148,7 +148,6 @@ App.ServiceConfigCheckbox = Ember.Checkbox.extend(App.ServiceConfigPopoverSuppor
 
 });
 
-<!-- {{bindAttr name="view.name" value="option"}}  '<input type="radio" {{bindAttr name = "view.name" value="view.obj"}}>',-->
 App.ServiceConfigRadioButtons = Ember.View.extend({
   template: Ember.Handlebars.compile([
     '{{#each option in view.options}}',
@@ -303,7 +302,8 @@ App.ServiceConfigMasterHostsView = Ember.View.extend(App.ServiceConfigMultipleHo
       }),
       onPrimary:function(){
         this.hide();
-      }
+      },
+      secondary: null
     });
   }
 

+ 1 - 0
ambari-web/app/views/wizard/step9_view.js

@@ -125,6 +125,7 @@ App.HostStatusView = Em.View.extend({
       onPrimary: function () {
         this.hide();
       },
+      secondary: null,
       controllerBinding: context,
       bodyClass: Ember.View.extend({
         templateName: require('templates/wizard/step9HostTasksLogPopup'),

+ 5 - 0
ambari-web/pom.xml

@@ -58,6 +58,11 @@
                 <exec dir="${basedir}" executable="brunch" failonerror="false">
                   <arg value="build"/>
                 </exec>
+                <exec dir="${basedir}" executable="gzip" failonerror="false">
+                  <arg value="public/javascripts/app.js"/>
+                  <arg value="public/javascripts/vendor.js"/>
+                  <arg value="public/stylesheets/app.css"/>
+                </exec>
               </target>
             </configuration>
           </execution>