Browse Source

AMBARI-1145. Cluster Management refactoring. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1431802 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 years ago
parent
commit
69b7eb284f
30 changed files with 242 additions and 80 deletions
  1. 0 0
      ambari-web/app/assets/data/services/metrics/mapreduce/tasks_running_waiting.json
  2. 1 1
      ambari-web/app/controllers/global/cluster_controller.js
  3. 3 0
      ambari-web/app/controllers/login_controller.js
  4. 12 0
      ambari-web/app/controllers/main/apps_controller.js
  5. 3 0
      ambari-web/app/controllers/main/host/add_controller.js
  6. 3 0
      ambari-web/app/controllers/main/service/add_controller.js
  7. 1 3
      ambari-web/app/controllers/wizard.js
  8. 8 4
      ambari-web/app/controllers/wizard/step10_controller.js
  9. 1 0
      ambari-web/app/controllers/wizard/step3_controller.js
  10. 16 5
      ambari-web/app/controllers/wizard/step8_controller.js
  11. 6 3
      ambari-web/app/controllers/wizard/step9_controller.js
  12. 8 1
      ambari-web/app/data/config_mapping.js
  13. 5 0
      ambari-web/app/data/review_configs.js
  14. 9 9
      ambari-web/app/messages.js
  15. 4 1
      ambari-web/app/routes/installer.js
  16. 1 1
      ambari-web/app/templates/main/dashboard/service/mapreduce.hbs
  17. 2 0
      ambari-web/app/templates/main/host/summary.hbs
  18. 2 0
      ambari-web/app/templates/main/service/info/configs.hbs
  19. 2 8
      ambari-web/app/templates/main/service/info/summary/zookeeper.hbs
  20. 29 21
      ambari-web/app/templates/wizard/step8.hbs
  21. 1 1
      ambari-web/app/utils/data_table.js
  22. 4 2
      ambari-web/app/utils/misc.js
  23. 1 1
      ambari-web/app/views.js
  24. 5 1
      ambari-web/app/views/main/apps_view.js
  25. 1 1
      ambari-web/app/views/main/service/info/metrics/mapreduce/map_slots.js
  26. 8 8
      ambari-web/app/views/main/service/info/metrics/mapreduce/tasks_running_waiting.js
  27. 15 1
      ambari-web/app/views/main/service/info/summary.js
  28. 11 8
      ambari-web/app/views/wizard/controls_view.js
  29. 5 0
      ambari-web/app/views/wizard/step8_view.js
  30. 75 0
      ambari-web/vendor/scripts/jquery.jqprint-0.3.js

+ 0 - 0
ambari-web/app/assets/data/services/metrics/mapreduce/jobs_running_waiting.json → ambari-web/app/assets/data/services/metrics/mapreduce/tasks_running_waiting.json


+ 1 - 1
ambari-web/app/controllers/global/cluster_controller.js

@@ -145,7 +145,7 @@ App.ClusterController = Em.Controller.extend({
       }
       }
       return null;
       return null;
     }
     }
-  }.property('App.router.updateController.isUpdated'),
+  }.property('App.router.updateController.isUpdated','dataLoadList.services'),
 
 
   isNagiosInstalled:function () {
   isNagiosInstalled:function () {
     if (App.testMode) {
     if (App.testMode) {

+ 3 - 0
ambari-web/app/controllers/login_controller.js

@@ -27,6 +27,9 @@ App.LoginController = Em.Object.extend({
 
 
   errorMessage: '',
   errorMessage: '',
 
 
+  isAdmin: function(){
+    return App.db.getUser().admin;
+  }.property('loginName'),
 
 
   submit: function (e) {
   submit: function (e) {
     this.set('errorMessage', '');
     this.set('errorMessage', '');

+ 12 - 0
ambari-web/app/controllers/main/apps_controller.js

@@ -40,6 +40,18 @@ App.MainAppsController = Em.ArrayController.extend({
     this.get('content').findProperty('id', id).set('isFiltered', true);
     this.get('content').findProperty('id', id).set('isFiltered', true);
     this.set('filteredRunsLength', this.get('content').filterProperty('isFiltered', true).length);
     this.set('filteredRunsLength', this.get('content').filterProperty('isFiltered', true).length);
   },
   },
+  /**
+   * Mark Runs as filtered
+   * @param ids array of Run id
+   */
+  filterFilteredRuns: function(ids) {
+    this.get('content').filter(function(item) {
+      if ($.inArray(item.get('id'), ids) !== -1) {
+        item.set('isFiltered', true);
+      }
+    });
+    this.set('filteredRunsLength', this.get('content').filterProperty('isFiltered', true).length);
+  },
   /**
   /**
    * Identifier of the last starred/unstarred run
    * Identifier of the last starred/unstarred run
    */
    */

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

@@ -517,6 +517,8 @@ App.AddHostController = App.WizardController.extend({
    */
    */
   clearAllSteps: function () {
   clearAllSteps: function () {
     this.clearInstallOptions();
     this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
   },
   },
 
 
   /**
   /**
@@ -524,6 +526,7 @@ App.AddHostController = App.WizardController.extend({
    */
    */
   finish: function () {
   finish: function () {
     this.setCurrentStep('1');
     this.setCurrentStep('1');
+    this.clearAllSteps();
     this.clearStorageData();
     this.clearStorageData();
     App.router.get('updateController').updateAll();
     App.router.get('updateController').updateAll();
   }
   }

+ 3 - 0
ambari-web/app/controllers/main/service/add_controller.js

@@ -555,6 +555,8 @@ App.AddServiceController = App.WizardController.extend({
    */
    */
   clearAllSteps: function () {
   clearAllSteps: function () {
     this.clearInstallOptions();
     this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
   },
   },
 
 
   /**
   /**
@@ -562,6 +564,7 @@ App.AddServiceController = App.WizardController.extend({
    */
    */
   finish: function () {
   finish: function () {
     this.setCurrentStep('1');
     this.setCurrentStep('1');
+    this.clearAllSteps();
     this.clearStorageData();
     this.clearStorageData();
     App.router.get('updateController').updateAll();
     App.router.get('updateController').updateAll();
   }
   }

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

@@ -244,13 +244,11 @@ App.WizardController = Em.Controller.extend({
    * @param isRetry
    * @param isRetry
    */
    */
   installServices: function (isRetry) {
   installServices: function (isRetry) {
-    if (!isRetry && this.get('content.cluster.requestId')) {
-      return;
-    }
 
 
     // clear requests since we are installing services
     // clear requests since we are installing services
     // and we don't want to get tasks for previous install attempts
     // and we don't want to get tasks for previous install attempts
     this.set('content.cluster.oldRequestsId', []);
     this.set('content.cluster.oldRequestsId', []);
+    this.set('content.cluster.requestId', null);
 
 
     var self = this;
     var self = this;
     var clusterName = this.get('content.cluster.name');
     var clusterName = this.get('content.cluster.name');

+ 8 - 4
ambari-web/app/controllers/wizard/step10_controller.js

@@ -29,8 +29,12 @@ App.WizardStep10Controller = Em.Controller.extend({
     console.log("TRACE: Loading step10: Summary Page");
     console.log("TRACE: Loading step10: Summary Page");
     this.clearStep();
     this.clearStep();
     this.loadInstalledHosts(this.loadRegisteredHosts());
     this.loadInstalledHosts(this.loadRegisteredHosts());
-    var installFlag = this.loadMasterComponents();
-    var startFlag = this.loadStartedServices();
+    var installFlag = true;
+    var startFlag = true;
+    if (this.get('content.controllerName') == 'installerController') {
+      installFlag = this.loadMasterComponents();
+      startFlag = this.loadStartedServices();
+    }
     if (installFlag && startFlag) {
     if (installFlag && startFlag) {
       this.loadInstallTime();
       this.loadInstallTime();
     }
     }
@@ -342,9 +346,9 @@ App.WizardStep10Controller = Em.Controller.extend({
       var seconds = Math.floor((this.get('content.cluster.installTime') - minutes) * secondsPerMinute);
       var seconds = Math.floor((this.get('content.cluster.installTime') - minutes) * secondsPerMinute);
       var statement;
       var statement;
       if (minutes !== 0) {
       if (minutes !== 0) {
-        statement = 'Install and start of all services completed in ' + minutes + ' minutes and ' + seconds + ' seconds';
+        statement = 'Install and start completed in ' + minutes + ' minutes and ' + seconds + ' seconds';
       } else {
       } else {
-        statement = 'Install and start of all services completed in ' + seconds + ' seconds';
+        statement = 'Install and start completed in ' + seconds + ' seconds';
       }
       }
       this.get('clusterInfo').pushObject(Ember.Object.create({
       this.get('clusterInfo').pushObject(Ember.Object.create({
         id: 5,
         id: 5,

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

@@ -266,6 +266,7 @@ App.WizardStep3Controller = Em.Controller.extend({
       type: 'GET',
       type: 'GET',
       url: url,
       url: url,
       timeout: App.timeout,
       timeout: App.timeout,
+      cache: false,
       success: function (data) {
       success: function (data) {
         if (data.hostsStatus !== null) {
         if (data.hostsStatus !== null) {
           // in case of bootstrapping just one host, the server returns an object rather than an array, so
           // in case of bootstrapping just one host, the server returns an object rather than an array, so

+ 16 - 5
ambari-web/app/controllers/wizard/step8_controller.js

@@ -168,6 +168,9 @@ App.WizardStep8Controller = Em.Controller.extend({
    * Set all site property that are derived from other site-properties
    * Set all site property that are derived from other site-properties
    */
    */
   setConfigValue: function (uiConfig, config) {
   setConfigValue: function (uiConfig, config) {
+    if (config.value == null) {
+      return;
+    }
     var fkValue = config.value.match(/<(foreignKey.*?)>/g);
     var fkValue = config.value.match(/<(foreignKey.*?)>/g);
     if (fkValue) {
     if (fkValue) {
       fkValue.forEach(function (_fkValue) {
       fkValue.forEach(function (_fkValue) {
@@ -358,6 +361,14 @@ App.WizardStep8Controller = Em.Controller.extend({
    */
    */
   loadClusterInfo: function () {
   loadClusterInfo: function () {
 
 
+    //Admin name
+    var admin = this.rawContent.findProperty('config_name', 'Admin');
+    admin.config_value = App.db.getLoginName();
+    console.log("STEP8: the value of content cluster name: " + App.db.getLoginName());
+    if (admin.config_value) {
+      this.get('clusterInfo').pushObject(Ember.Object.create(admin));
+    }
+
     // cluster name
     // cluster name
     var cluster = this.rawContent.findProperty('config_name', 'cluster');
     var cluster = this.rawContent.findProperty('config_name', 'cluster');
     cluster.config_value = this.get('content.cluster.name');
     cluster.config_value = this.get('content.cluster.name');
@@ -756,7 +767,7 @@ App.WizardStep8Controller = Em.Controller.extend({
             clusterName: this.get('clusterName'),
             clusterName: this.get('clusterName'),
             clusterState: 'CLUSTER_DEPLOY_PREP_2',
             clusterState: 'CLUSTER_DEPLOY_PREP_2',
             wizardControllerName: this.get('content.controllerName'),
             wizardControllerName: this.get('content.controllerName'),
-            localdb: App.db.data,
+            localdb: App.db.data
           });
           });
           break;
           break;
 
 
@@ -1380,13 +1391,13 @@ App.WizardStep8Controller = Em.Controller.extend({
       case 'MAPREDUCE':
       case 'MAPREDUCE':
         return {config: {'global': 'version1', 'core-site': 'version1', 'mapred-site': 'version1'}};
         return {config: {'global': 'version1', 'core-site': 'version1', 'mapred-site': 'version1'}};
       case 'HBASE':
       case 'HBASE':
-        return {config: {'global': 'version1', 'core-site': 'version1', 'hbase-site': 'version1'}};
+        return {config: {'global': 'version1', 'hbase-site': 'version1'}};
       case 'OOZIE':
       case 'OOZIE':
-        return {config: {'global': 'version1', 'core-site': 'version1', 'oozie-site': 'version1'}};
+        return {config: {'global': 'version1', 'oozie-site': 'version1'}};
       case 'HIVE':
       case 'HIVE':
-        return {config: {'global': 'version1', 'core-site': 'version1', 'hive-site': 'version1'}};
+        return {config: {'global': 'version1', 'hive-site': 'version1'}};
       case 'WEBHCAT':
       case 'WEBHCAT':
-        return {config: {'global': 'version1', 'core-site': 'version1', 'webhcat-site': 'version1'}};
+        return {config: {'global': 'version1', 'webhcat-site': 'version1'}};
       default:
       default:
         return {config: {'global': 'version1'}};
         return {config: {'global': 'version1'}};
     }
     }

+ 6 - 3
ambari-web/app/controllers/wizard/step9_controller.js

@@ -355,10 +355,10 @@ App.WizardStep9Controller = Em.Controller.extend({
     return polledData.everyProperty('Tasks.status', 'COMPLETED');
     return polledData.everyProperty('Tasks.status', 'COMPLETED');
   },
   },
 
 
-  // for DATANODE, JOBTRACKER, HBASE_REGIONSERVER, and GANGLIA_MONITOR, if more than 50% fail, then it's a fatal error;
+  // for DATANODE, TASKTRACKER, HBASE_REGIONSERVER, and GANGLIA_MONITOR, if more than 50% fail, then it's a fatal error;
   // otherwise, it's only a warning and installation/start can continue
   // otherwise, it's only a warning and installation/start can continue
   getSuccessFactor: function (role) {
   getSuccessFactor: function (role) {
-    return ['DATANODE', 'JOBTRACKER', 'HBASE_REGIONSERVER', 'GANGLIA_MONITOR'].contains(role) ? 50 : 100;
+    return ['DATANODE', 'TASKTRACKER', 'HBASE_REGIONSERVER', 'GANGLIA_MONITOR'].contains(role) ? 50 : 100;
   },
   },
 
 
   isStepFailed: function (polledData) {
   isStepFailed: function (polledData) {
@@ -436,9 +436,12 @@ App.WizardStep9Controller = Em.Controller.extend({
           this.set('status', 'success');
           this.set('status', 'success');
         } else {
         } else {
           if (this.isStepFailed(polledData)) {
           if (this.isStepFailed(polledData)) {
-            clusterStatus.status = 'START FAILED';      // 'START FAILED' implies to step10 that installation was successful but start failed
+            clusterStatus.status = 'START FAILED'; // 'START FAILED' implies to step10 that installation was successful but start failed
             this.set('status', 'failed');
             this.set('status', 'failed');
             this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData), 'failed');
             this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData), 'failed');
+          } else {
+            clusterStatus.status = 'START FAILED';
+            this.set('status', 'warning');
           }
           }
         }
         }
         App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);
         App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);

+ 8 - 1
ambari-web/app/data/config_mapping.js

@@ -59,6 +59,13 @@ module.exports = [
     "value": "<templateName[0]>",
     "value": "<templateName[0]>",
     "filename": "core-site.xml"
     "filename": "core-site.xml"
   },
   },
+  {
+    "name": "hadoop.proxyuser.<foreignKey[0]>.hosts",
+    "templateName": ["hivemetastore_host"],
+    "foreignKey": ["hive_user"],
+    "value": "<templateName[0]>",
+    "filename": "core-site.xml"
+  },
   {
   {
     "name": "hadoop.proxyuser.<foreignKey[0]>.groups",
     "name": "hadoop.proxyuser.<foreignKey[0]>.groups",
     "templateName": ["proxyuser_group"],
     "templateName": ["proxyuser_group"],
@@ -766,7 +773,7 @@ module.exports = [
     "name": "templeton.hive.properties",
     "name": "templeton.hive.properties",
     "templateName": ["hivemetastore_host"],
     "templateName": ["hivemetastore_host"],
     "foreignKey": null,
     "foreignKey": null,
-    "value": "hive.metastore.local=false,hive.metastore.uris=thrift://<templateName[0]>:9083,hive.metastore.sasl.enabled=no",
+    "value": "hive.metastore.local=false,hive.metastore.uris=thrift://<templateName[0]>:9083,hive.metastore.sasl.enabled=yes,hive.metastore.execute.setugi=true",
     "filename": "webhcat-site.xml"
     "filename": "webhcat-site.xml"
   },
   },
   {
   {

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

@@ -18,6 +18,11 @@
 
 
 module.exports = [
 module.exports = [
 
 
+  {
+    config_name: 'Admin',
+    display_name: 'Admin Name',
+    config_value: ''
+  },
   {
   {
     config_name: 'cluster',
     config_name: 'cluster',
     display_name: 'Cluster Name',
     display_name: 'Cluster Name',

+ 9 - 9
ambari-web/app/messages.js

@@ -70,11 +70,11 @@ Em.I18n.translations = {
   'installer.step1.clusterName.error.specialChar':'Cluster Name cannot contain special characters',
   'installer.step1.clusterName.error.specialChar':'Cluster Name cannot contain special characters',
 
 
   'installer.step2.header':'Install Options',
   'installer.step2.header':'Install Options',
-  'installer.step2.body':'Enter the list of hosts to be included in the cluster, provide your SSH key, and optionally specify a local repository.',
+  'installer.step2.body':'Enter the list of hosts to be included in the cluster and provide your SSH key.',
   'installer.step2.targetHosts':'Target Hosts',
   'installer.step2.targetHosts':'Target Hosts',
   'installer.step2.targetHosts.info':'Enter a list of host names, one per line',
   'installer.step2.targetHosts.info':'Enter a list of host names, one per line',
   'installer.step2.hostPattern.tooltip.title':'Pattern Expressions',
   'installer.step2.hostPattern.tooltip.title':'Pattern Expressions',
-  'installer.step2.hostPattern.tooltip.content':'You can use pattern expressions to specify a number of target hosts. For example, to specify host1 thru host10, enter host[1-10] in the target hosts textarea.',
+  'installer.step2.hostPattern.tooltip.content':'You can use pattern expressions to specify a number of target hosts. For example, to specify host01.domain thru host10.domain, enter host[01-10].domain in the target hosts textarea.',
   'installer.step2.hostName.error.required':'You must specify at least one host name',
   'installer.step2.hostName.error.required':'You must specify at least one host name',
   'installer.step2.hostName.error.notRequired':'Host Names will be ignored if not using SSH to automatically configure hosts',
   'installer.step2.hostName.error.notRequired':'Host Names will be ignored if not using SSH to automatically configure hosts',
   'installer.step2.hostName.error.invalid':'Invalid Host Name(s)',
   'installer.step2.hostName.error.invalid':'Invalid Host Name(s)',
@@ -92,7 +92,7 @@ Em.I18n.translations = {
   'installer.step2.localRepo.label_instead':'instead of downloading software packages from the Internet',
   'installer.step2.localRepo.label_instead':'instead of downloading software packages from the Internet',
   'installer.step2.localRepo.error.required':'Local repository file path is required',
   'installer.step2.localRepo.error.required':'Local repository file path is required',
   'installer.step2.localRepo.tooltip.title':'Local Software Repository',
   'installer.step2.localRepo.tooltip.title':'Local Software Repository',
-  'installer.step2.localRepo.tooltip.content': 'The cluster install requires access to the Internet to fetch software ' +
+  'installer.step2.localRepo.tooltip.content': 'The install process requires access to the Internet to fetch software ' +
     'from a remote repository. In some cases, adequate bandwidth is not available and you want to prevent downloading ' +
     'from a remote repository. In some cases, adequate bandwidth is not available and you want to prevent downloading ' +
     'packages from the remote repository over and over again. Other times, Internet access is not available from the ' +
     'packages from the remote repository over and over again. Other times, Internet access is not available from the ' +
     'hosts in your cluster. In these situations, you must set up a version of the repository that your machines can ' +
     'hosts in your cluster. In these situations, you must set up a version of the repository that your machines can ' +
@@ -143,13 +143,13 @@ Em.I18n.translations = {
   'installer.step7.attentionNeeded':'<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
   'installer.step7.attentionNeeded':'<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
 
 
   'installer.step8.header':'Review',
   'installer.step8.header':'Review',
-  'installer.step8.body':'Please review the cluster configuration before installation',
+  'installer.step8.body':'Please review the configuration before installation',
 
 
   'installer.step9.header':'Install, Start and Test',
   'installer.step9.header':'Install, Start and Test',
-  'installer.step9.body':'Please wait while the selected services are installed, started, and tested on your new cluster.',
-  'installer.step9.status.success':'Successfully installed and started the cluster.',
-  'installer.step9.status.warning':'Installed and started the cluster with some warnings.',
-  'installer.step9.status.failed':'Failed to install/start the cluster.',
+  'installer.step9.body':'Please wait while the selected services are installed and started.',
+  'installer.step9.status.success':'Successfully installed and started the services.',
+  'installer.step9.status.warning':'Installed and started the services with some warnings.',
+  'installer.step9.status.failed':'Failed to install/start the services.',
   'installer.step9.host.status.success':'Success',
   'installer.step9.host.status.success':'Success',
   'installer.step9.host.status.warning':'Warnings encountered',
   'installer.step9.host.status.warning':'Warnings encountered',
   'installer.step9.host.status.failed':'Failures encountered',
   'installer.step9.host.status.failed':'Failures encountered',
@@ -157,7 +157,7 @@ Em.I18n.translations = {
   'installer.step9.hostLog.popup.header':'Tasks. executed on ',
   'installer.step9.hostLog.popup.header':'Tasks. executed on ',
 
 
   'installer.step10.header':'Summary',
   'installer.step10.header':'Summary',
-  'installer.step10.body':'Here is the summary of the cluster install process.',
+  'installer.step10.body':'Here is the summary of the install process.',
 
 
 
 
   'form.create':'Create',
   'form.create':'Create',

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

@@ -292,7 +292,7 @@ module.exports = Em.Route.extend({
       var controller = router.get('installerController');
       var controller = router.get('installerController');
       controller.setCurrentStep('9');
       controller.setCurrentStep('9');
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
-      if (!App.testMode) { // if test mode is ON don't disable prior steps link.
+      if (!App.testMode) {
         controller.setLowerStepsDisable(9);
         controller.setLowerStepsDisable(9);
       }
       }
       controller.connectOutlet('wizardStep9', controller.get('content'));
       controller.connectOutlet('wizardStep9', controller.get('content'));
@@ -342,6 +342,9 @@ module.exports = Em.Route.extend({
       var controller = router.get('installerController');
       var controller = router.get('installerController');
       controller.setCurrentStep('10');
       controller.setCurrentStep('10');
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
+      if (!App.testMode) {
+        controller.setLowerStepsDisable(10);
+      }
       controller.connectOutlet('wizardStep10', controller.get('content'));
       controller.connectOutlet('wizardStep10', controller.get('content'));
     },
     },
     back: Em.Router.transitionTo('step9'),
     back: Em.Router.transitionTo('step9'),

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

@@ -122,7 +122,7 @@
     </table>
     </table>
   </div>
   </div>
 <div class="dashboard-mini-chart span2">
 <div class="dashboard-mini-chart span2">
-  {{view App.ChartServiceMetricsMapReduce_JobsRunningWaiting}}
+  {{view App.ChartServiceMetricsMapReduce_TasksRunningWaiting}}
   
   
   {{#if view.service.quickLinks.length}}
   {{#if view.service.quickLinks.length}}
   {{#view App.QuickViewLinks contentBinding="view.service"}}
   {{#view App.QuickViewLinks contentBinding="view.service"}}

+ 2 - 0
ambari-web/app/templates/main/host/summary.hbs

@@ -54,6 +54,7 @@
               <a href="#" {{action routeToService component.service target="controller"  }}>{{component.service.displayName}}</a>
               <a href="#" {{action routeToService component.service target="controller"  }}>{{component.service.displayName}}</a>
             </div>
             </div>
             <div class="span4">
             <div class="span4">
+              {{#if controller.isAdmin}}
               <div class="btn-group">
               <div class="btn-group">
                 <a {{ bindAttr class=":btn :dropdown-toggle view.disabledClass"}} data-toggle="dropdown">
                 <a {{ bindAttr class=":btn :dropdown-toggle view.disabledClass"}} data-toggle="dropdown">
                   Action
                   Action
@@ -84,6 +85,7 @@
                   </li>
                   </li>
                 </ul>
                 </ul>
               </div>
               </div>
+              {{/if}}
             </div>
             </div>
           {{/view}}
           {{/view}}
           </div>
           </div>

+ 2 - 0
ambari-web/app/templates/main/service/info/configs.hbs

@@ -54,11 +54,13 @@
           </div>
           </div>
       {{/each}}
       {{/each}}
     </div>
     </div>
+    {{#if App.router.loginController.isAdmin}}
     <p class="pull-right">
     <p class="pull-right">
         <!--<input class="btn btn-primary" type="button" value="Save and apply changes" {{!bindAttr disabled="isSubmitDisabled"}} />-->
         <!--<input class="btn btn-primary" type="button" value="Save and apply changes" {{!bindAttr disabled="isSubmitDisabled"}} />-->
         <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
         <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
           {{action restartServicePopup target="controller"}}>Save and apply changes</a>
           {{action restartServicePopup target="controller"}}>Save and apply changes</a>
     </p>
     </p>
+    {{/if}}
   {{else}}
   {{else}}
     <div class="spinner"></div>
     <div class="spinner"></div>
   {{/if}}
   {{/if}}

+ 2 - 8
ambari-web/app/templates/main/service/info/summary/zookeeper.hbs

@@ -19,19 +19,13 @@
 <tr>
 <tr>
   <td class="summary-label">Servers</td>
   <td class="summary-label">Servers</td>
   <td>
   <td>
-    {{#each view.servers}}
-      <a {{action filterHosts view.serversHost}} href="javascript:void(null)">{{host}}</a>{{#if isComma}}, {{/if}}
-      {{#if isAnd}} and {{/if}}
-    {{/each}}
+      <a {{action filterHosts view.serversHost}} href="javascript:void(null)">{{view.servers.length}} ZooKeeper Server{{#if view.hasManyServers}}s{{/if}}</a>
   </td>
   </td>
 </tr>
 </tr>
 
 
 <tr>
 <tr>
   <td class="summary-label">Clients</td>
   <td class="summary-label">Clients</td>
   <td>
   <td>
-    {{#each view.clients}}
-      <a {{action filterHosts view.clientObj}} href="javascript:void(null)">{{displayName}}</a>{{#if isComma}}, {{/if}}
-      {{#if isAnd}} and {{/if}}
-    {{/each}}
+      <a {{action filterHosts view.clientObj}} href="javascript:void(null)">{{view.clients.length}} ZooKeeper Client{{#if view.hasManyClients}}s{{/if}}</a>
   </td>
   </td>
 </tr>
 </tr>

+ 29 - 21
ambari-web/app/templates/wizard/step8.hbs

@@ -19,32 +19,40 @@
 <h2>{{t installer.step8.header}}</h2>
 <h2>{{t installer.step8.header}}</h2>
 
 
 <div class="alert alert-info">
 <div class="alert alert-info">
-    {{t installer.step8.body}}
+  {{t installer.step8.body}}
 </div>
 </div>
+
 <div id="step8-content" class="well pre-scrollable">
 <div id="step8-content" class="well pre-scrollable">
-{{#each item in controller.clusterInfo}}
-<p>
-		<b>{{item.display_name}}</b> : {{item.config_value}}
-</p>
-{{/each}}
+    <div id="printReview">
+        <a class="btn btn-info pull-right" {{action printReview target="view"}}>Print</a> <br/>
+    </div>
+    <div id="step8-info">
+      {{#each item in controller.clusterInfo}}
+          <p>
+              <b>{{item.display_name}}</b> : {{item.config_value}}
+          </p>
+      {{/each}}
 
 
-	<div>
-		<p><b>Services</b></p>
-		{{#each controller.services}}
-		<div>
-			<ul><em><b>{{display_name}}</b></em>
+        <div>
+            <p><b>Services</b></p>
+          {{#each controller.services}}
+              <div>
+                  <ul><em><b>{{display_name}}</b></em>
 
 
-				<div>
-					{{#each component in this.service_components}}
-					<ul><span class="text text-info">{{component.display_name }} : </span>{{component.component_value}}</ul>
-					{{/each}}
-				</div>
-			</ul>
-		</div>
-		{{/each}}
-	</div>
+                      <div>
+                        {{#each component in this.service_components}}
+                            <ul><span class="text text-info">{{component.display_name }}
+                                : </span>{{component.component_value}}</ul>
+                        {{/each}}
+                      </div>
+                  </ul>
+              </div>
+          {{/each}}
+        </div>
+    </div>
 </div>
 </div>
 <div class="btn-area">
 <div class="btn-area">
     <a class="btn pull-left" {{action back href="true"}}>&larr; Back</a>
     <a class="btn pull-left" {{action back href="true"}}>&larr; Back</a>
-    <a class="btn btn-success pull-right" id="spinner" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action submit target="controller"}}>Deploy &rarr;</a>
+    <a class="btn btn-success pull-right"
+       id="spinner" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action submit target="controller"}}>Deploy &rarr;</a>
 </div>
 </div>

+ 1 - 1
ambari-web/app/utils/data_table.js

@@ -229,7 +229,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
         var compareScale = rangeExp.charAt(rangeExp.length - 1);
         var compareScale = rangeExp.charAt(rangeExp.length - 1);
         var compareValue = isNaN(parseInt(compareScale), 10) ? parseInt(rangeExp.substr(1, rangeExp.length - 2), 10) : parseInt(rangeExp.substr(1, rangeExp.length - 1), 10);
         var compareValue = isNaN(parseInt(compareScale), 10) ? parseInt(rangeExp.substr(1, rangeExp.length - 2), 10) : parseInt(rangeExp.substr(1, rangeExp.length - 1), 10);
         rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
         rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
-        var convertedRowValue = parseInt(rowValue.substr(0, 2), 10) * 3600 + parseInt(rowValue.substr(3, 2), 10) * 60 + parseInt(rowValue.substr(6, 2), 10);
+        var convertedRowValue = parseInt(rowValue.substr(0, rowValue.indexOf('secs')), 10);
         switch (compareScale) {
         switch (compareScale) {
           case 'm':
           case 'm':
             convertedRowValue /= 60;
             convertedRowValue /= 60;

+ 4 - 2
ambari-web/app/utils/misc.js

@@ -25,9 +25,11 @@ module.exports = {
         value = '<1KB';
         value = '<1KB';
       } else {
       } else {
         if (value < 1048576) {
         if (value < 1048576) {
-          value = (Math.round(value / 102.4) / 10).toFixed(1) + 'KB';
+          value = (value / 1024).toFixed(1) + 'KB';
+        } else  if (value >= 1048576 && value < 1073741824){
+          value = (value / 1048576).toFixed(1) + 'MB';
         } else {
         } else {
-          value = (Math.round(value / 104857.6) / 10).toFixed(1) + 'MB';
+          value = (value / 1073741824).toFixed(2) + 'GB';
         }
         }
       }
       }
     }
     }

+ 1 - 1
ambari-web/app/views.js

@@ -93,7 +93,7 @@ require('views/main/service/info/metrics/mapreduce/gc');
 require('views/main/service/info/metrics/mapreduce/jvm_threads');
 require('views/main/service/info/metrics/mapreduce/jvm_threads');
 require('views/main/service/info/metrics/mapreduce/jvm_heap');
 require('views/main/service/info/metrics/mapreduce/jvm_heap');
 require('views/main/service/info/metrics/mapreduce/rpc');
 require('views/main/service/info/metrics/mapreduce/rpc');
-require('views/main/service/info/metrics/mapreduce/jobs_running_waiting');
+require('views/main/service/info/metrics/mapreduce/tasks_running_waiting');
 require('views/main/service/info/metrics/mapreduce/jobs_status');
 require('views/main/service/info/metrics/mapreduce/jobs_status');
 require('views/main/service/info/metrics/mapreduce/map_slots');
 require('views/main/service/info/metrics/mapreduce/map_slots');
 require('views/main/service/info/metrics/mapreduce/reduce_slots');
 require('views/main/service/info/metrics/mapreduce/reduce_slots');

+ 5 - 1
ambari-web/app/views/main/apps_view.js

@@ -394,7 +394,9 @@ App.MainAppsView = Em.View.extend({
       });
       });
     });
     });
     this.get('oTable').fnSettings()._iDisplayLength = 10;
     this.get('oTable').fnSettings()._iDisplayLength = 10;
+    $('#dataTable_length select option:eq(0)').attr('selected', 'selected');
     this.get('oTable').fnDraw(false);
     this.get('oTable').fnDraw(false);
+
     console.log('Rendering Apps Table:');
     console.log('Rendering Apps Table:');
     console.log('Start - ', d.toLocaleTimeString());
     console.log('Start - ', d.toLocaleTimeString());
     console.log('End   - ', (new Date()).toLocaleTimeString());
     console.log('End   - ', (new Date()).toLocaleTimeString());
@@ -486,9 +488,11 @@ App.MainAppsView = Em.View.extend({
   averageRefresh:function() {
   averageRefresh:function() {
     var rows = this.get('oTable')._('tr', {"filter":"applied"});
     var rows = this.get('oTable')._('tr', {"filter":"applied"});
     this.get('controller').clearFilteredRuns();
     this.get('controller').clearFilteredRuns();
+    var ids = [];
     for(var i = 0; i < rows.length; i++) {
     for(var i = 0; i < rows.length; i++) {
-      this.get('controller').addFilteredRun(rows[i][1]);
+      ids.push(rows[i][1]);
     }
     }
+    this.get('controller').filterFilteredRuns(ids);
   }.observes('filtered'),
   }.observes('filtered'),
   /**
   /**
    * dataTable filter views
    * dataTable filter views

+ 1 - 1
ambari-web/app/views/main/service/info/metrics/mapreduce/map_slots.js

@@ -28,7 +28,7 @@ var App = require('app');
  */
  */
 App.ChartServiceMetricsMapReduce_MapSlots = App.ChartLinearTimeView.extend({
 App.ChartServiceMetricsMapReduce_MapSlots = App.ChartLinearTimeView.extend({
   id: "service-metrics-mapreduce-map-slots",
   id: "service-metrics-mapreduce-map-slots",
-  title: "Map Slot Utilization",
+  title: "Map Slots Utilization",
   renderer: 'line',
   renderer: 'line',
   url: function () {
   url: function () {
     return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER?fields=metrics/mapred/jobtracker/occupied_map_slots[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/reserved_map_slots[{fromSeconds},{toSeconds},{stepSeconds}]", {
     return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER?fields=metrics/mapred/jobtracker/occupied_map_slots[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/reserved_map_slots[{fromSeconds},{toSeconds},{stepSeconds}]", {

+ 8 - 8
ambari-web/app/views/main/service/info/metrics/mapreduce/jobs_running_waiting.js → ambari-web/app/views/main/service/info/metrics/mapreduce/tasks_running_waiting.js

@@ -26,14 +26,14 @@ var App = require('app');
  * @extends Ember.Object
  * @extends Ember.Object
  * @extends Ember.View
  * @extends Ember.View
  */
  */
-App.ChartServiceMetricsMapReduce_JobsRunningWaiting = App.ChartLinearTimeView.extend({
-  id: "service-metrics-mapreduce-jobs-running-waiting",
-  title: "Jobs (Running/Waiting)",
+App.ChartServiceMetricsMapReduce_TasksRunningWaiting = App.ChartLinearTimeView.extend({
+  id: "service-metrics-mapreduce-tasks-running-waiting",
+  title: "Tasks (Running/Waiting)",
   renderer: 'line',
   renderer: 'line',
   url: function () {
   url: function () {
     return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER?fields=metrics/mapred/jobtracker/running_maps[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/running_reduces[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/waiting_maps[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/waiting_reduces[{fromSeconds},{toSeconds},{stepSeconds}]", {
     return App.formatUrl(App.apiPrefix + "/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER?fields=metrics/mapred/jobtracker/running_maps[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/running_reduces[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/waiting_maps[{fromSeconds},{toSeconds},{stepSeconds}],metrics/mapred/jobtracker/waiting_reduces[{fromSeconds},{toSeconds},{stepSeconds}]", {
       clusterName: App.router.get('clusterController.clusterName')
       clusterName: App.router.get('clusterController.clusterName')
-    }, "/data/services/metrics/mapreduce/jobs_running_waiting.json");
+    }, "/data/services/metrics/mapreduce/tasks_running_waiting.json");
   }.property('App.router.clusterController.clusterName'),
   }.property('App.router.clusterController.clusterName'),
 
 
   transformToSeries: function (jsonData) {
   transformToSeries: function (jsonData) {
@@ -44,16 +44,16 @@ App.ChartServiceMetricsMapReduce_JobsRunningWaiting = App.ChartLinearTimeView.ex
         var seriesData = jsonData.metrics.mapred.jobtracker[name];
         var seriesData = jsonData.metrics.mapred.jobtracker[name];
         switch (name) {
         switch (name) {
           case "running_maps":
           case "running_maps":
-            displayName = "Running Map Jobs";
+            displayName = "Running Map Tasks";
             break;
             break;
           case "running_reduces":
           case "running_reduces":
-            displayName = "Running Reduce Jobs";
+            displayName = "Running Reduce Tasks";
             break;
             break;
           case "waiting_maps":
           case "waiting_maps":
-            displayName = "Waiting Map Jobs";
+            displayName = "Waiting Map Tasks";
             break;
             break;
           case "waiting_reduces":
           case "waiting_reduces":
-            displayName = "Waiting Reduce Jobs";
+            displayName = "Waiting Reduce Tasks";
             break;
             break;
           default:
           default:
             break;
             break;

+ 15 - 1
ambari-web/app/views/main/service/info/summary.js

@@ -77,6 +77,20 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return result;
     return result;
   }.property('controller.content'),
   }.property('controller.content'),
 
 
+  hasManyServers: function () {
+    if (this.get('servers').length > 1) {
+      return true;
+    }
+    return false;
+  }.property('servers'),
+
+  hasManyClients: function () {
+    if (this.get('clients').length > 1) {
+      return true;
+    }
+    return false;
+  }.property('clients'),
+
   servers: function () {
   servers: function () {
     var result = [];
     var result = [];
     var service = this.get('controller.content');
     var service = this.get('controller.content');
@@ -286,7 +300,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
           break;
           break;
         case 'mapreduce':
         case 'mapreduce':
           graphs = [ App.ChartServiceMetricsMapReduce_JobsStatus.extend(),
           graphs = [ App.ChartServiceMetricsMapReduce_JobsStatus.extend(),
-            App.ChartServiceMetricsMapReduce_JobsRunningWaiting.extend(),
+            App.ChartServiceMetricsMapReduce_TasksRunningWaiting.extend(),
             App.ChartServiceMetricsMapReduce_MapSlots.extend(),
             App.ChartServiceMetricsMapReduce_MapSlots.extend(),
             App.ChartServiceMetricsMapReduce_ReduceSlots.extend(),
             App.ChartServiceMetricsMapReduce_ReduceSlots.extend(),
             App.ChartServiceMetricsMapReduce_GC.extend(),
             App.ChartServiceMetricsMapReduce_GC.extend(),

+ 11 - 8
ambari-web/app/views/wizard/controls_view.js

@@ -191,18 +191,21 @@ App.ServiceConfigRadioButton = Ember.Checkbox.extend({
     var components = this.get('parentView.serviceConfig.options');
     var components = this.get('parentView.serviceConfig.options');
     components.forEach(function (_component) {
     components.forEach(function (_component) {
       _component.foreignKeys.forEach(function (_componentName) {
       _component.foreignKeys.forEach(function (_componentName) {
-        var component = this.get('parentView.categoryConfigs').findProperty('name', _componentName);
-        if (_component.displayName === this.get('value')) {
-          component.set('isVisible', true);
-        } else {
-          component.set('isVisible', false);
+        if (this.get('parentView.categoryConfigs').someProperty('name', _componentName)) {
+          var component = this.get('parentView.categoryConfigs').findProperty('name', _componentName);
+          if (_component.displayName === this.get('value')) {
+            component.set('isVisible', true);
+          } else {
+            component.set('isVisible', false);
+          }
         }
         }
       }, this);
       }, this);
     }, this);
     }, this);
-  }.observes('checked'),
+  }.observes('checked') ,
+
   disabled: function () {
   disabled: function () {
-    return !this.get('serviceConfig.isEditable');
-  }.property('serviceConfig.isEditable')
+    return !this.get('parentView.serviceConfig.isEditable');
+  }.property('parentView.serviceConfig.isEditable')
 });
 });
 
 
 App.ServiceConfigComboBox = Ember.Select.extend(App.ServiceConfigPopoverSupport, {
 App.ServiceConfigComboBox = Ember.Select.extend(App.ServiceConfigPopoverSupport, {

+ 5 - 0
ambari-web/app/views/wizard/step8_view.js

@@ -29,6 +29,11 @@ App.WizardStep8View = Em.View.extend({
   },
   },
   spinner : null,
   spinner : null,
 
 
+  printReview: function() {
+    var o = $("#step8-info");
+    o.jqprint();
+  },
+
   showLoadingIndicator: function(){
   showLoadingIndicator: function(){
     if(this.get('controller.hasErrorOccurred')){
     if(this.get('controller.hasErrorOccurred')){
       $('.spinner').hide();
       $('.spinner').hide();

+ 75 - 0
ambari-web/vendor/scripts/jquery.jqprint-0.3.js

@@ -0,0 +1,75 @@
+// -----------------------------------------------------------------------
+// Eros Fratini - eros@recoding.it
+// jqprint 0.3
+//
+// - 19/06/2009 - some new implementations, added Opera support
+// - 11/05/2009 - first sketch
+//
+// Printing plug-in for jQuery, evolution of jPrintArea: http://plugins.jquery.com/project/jPrintArea
+// requires jQuery 1.3.x
+//
+// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+//------------------------------------------------------------------------
+
+(function($) {
+    var opt;
+
+    $.fn.jqprint = function (options) {
+        opt = $.extend({}, $.fn.jqprint.defaults, options);
+
+        var $element = (this instanceof jQuery) ? this : $(this);
+        
+        if (opt.operaSupport && $.browser.opera) 
+        { 
+            var tab = window.open("","jqPrint-preview");
+            tab.document.open();
+
+            var doc = tab.document;
+        }
+        else 
+        {
+            var $iframe = $("<iframe  />");
+        
+            if (!opt.debug) { $iframe.css({ position: "absolute", width: "0px", height: "0px", left: "-600px", top: "-600px" }); }
+
+            $iframe.appendTo("body");
+            var doc = $iframe[0].contentWindow.document;
+        }
+        
+        if (opt.importCSS)
+        {
+            if ($("link[media=print]").length > 0) 
+            {
+                $("link[media=print]").each( function() {
+                    doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' media='print' />");
+                });
+            }
+            else 
+            {
+                $("link").each( function() {
+                    doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' />");
+                });
+            }
+        }
+        
+        if (opt.printContainer) { doc.write($element.outer()); }
+        else { $element.each( function() { doc.write($(this).html()); }); }
+        
+        doc.close();
+        
+        (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).focus();
+        setTimeout( function() { (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).print(); if (tab) { tab.close(); } }, 1000);
+    }
+    
+    $.fn.jqprint.defaults = {
+		debug: false,
+		importCSS: true, 
+		printContainer: true,
+		operaSupport: true
+	};
+
+    // Thanks to 9__, found at http://users.livejournal.com/9__/380664.html
+    jQuery.fn.outer = function() {
+      return $($('<div></div>').html(this.clone())).html();
+    } 
+})(jQuery);