Bladeren bron

AMBARI-1145. Cluster Management refactoring. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1431809 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 jaren geleden
bovenliggende
commit
0087462d87

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

@@ -937,7 +937,7 @@
           "loginFailure_avg_time" : 0.0
         },
         "disk" : {
-          "disk_total" : 893.765,
+          "disk_total" : 0,
           "disk_free" : 845.624
         },
         "cpu" : {

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

@@ -316,7 +316,7 @@ App.ClusterController = Em.Controller.extend({
     }
 
     var clusterUrl = this.getUrl('/data/clusters/cluster.json', '?fields=Clusters');
-    var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=Hosts,host_components');
+    var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=Hosts,host_components,metrics/cpu,metrics/disk,metrics/load,metrics/memory');
     var usersUrl = App.testMode ? '/data/users/users.json' : App.apiPrefix + '/users/?fields=*';
     var racksUrl = "/data/racks/racks.json";
 

+ 1 - 1
ambari-web/app/controllers/main/host/details.js

@@ -264,7 +264,7 @@ App.MainHostDetailsController = Em.Controller.extend({
               timeout: App.timeout,
               success: function(){
                 var view = self.get('view');
-                view.loadDecommisionNodesList();
+                view.loadDecommissionNodesList();
               }
             };
             jQuery.ajax(persistPutAjax);

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

@@ -380,7 +380,10 @@ App.WizardController = Em.Controller.extend({
   },
 
   clear: function () {
-    this.set('content', Ember.Object.create({'controllerName': this.get('content.controllerName')}));
+    this.set('content', Ember.Object.create({
+      'controllerName': this.get('content.controllerName'),
+      'isWizard': !(this.get('content.controllerName') === 'installerController')
+    }));
     this.set('currentStep', 0);
     this.clearStorageData();
   },

+ 14 - 8
ambari-web/app/controllers/wizard/step2_controller.js

@@ -50,6 +50,14 @@ App.WizardStep2Controller = Em.Controller.extend({
   updateHostNameArr: function(){
     this.hostNameArr = this.get('hostNames').trim().split(new RegExp("\\s+", "g"));
     this.patternExpression();
+    var installedHostNames = App.Host.find().mapProperty('hostName');
+    var tempArr = [];
+    for (i = 0; i < this.hostNameArr.length; i++) {
+      if (!installedHostNames.contains(this.hostNameArr[i])) {
+        tempArr.push(this.hostNameArr[i]);
+      }
+    }
+    this.set('hostNameArr', tempArr);
   },
 
   isAllHostNamesValid: function () {
@@ -146,6 +154,11 @@ App.WizardStep2Controller = Em.Controller.extend({
 
     this.updateHostNameArr();
 
+    if (!this.hostNameArr.length) {
+      this.set('hostsError', Em.I18n.t('installer.step2.hostName.error.required'));
+      return false;
+    }
+
     if(this.isPattern)
     {
       this.hostNamePatternPopup(this.hostNameArr);
@@ -243,14 +256,7 @@ App.WizardStep2Controller = Em.Controller.extend({
   }.property('hostsError', 'sshKeyError'),
 
   saveHosts: function(){
-    var installedHosts = App.Host.find();
-    var newHosts = this.getHostInfo();
-    for (var host in newHosts) {
-      if (installedHosts.someProperty('hostName', host)) {
-        delete newHosts[host]
-      }
-    }
-    this.set('content.hosts', newHosts);
+    this.set('content.hosts', this.getHostInfo());
     App.router.send('next');
   }
 

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

@@ -947,7 +947,6 @@ App.WizardStep8Controller = Em.Controller.extend({
     var masterHosts = this.get('content.masterComponentHosts');
     var slaveHosts = this.get('content.slaveComponentHosts');
     var clients = this.get('content.clients');
-    var clientHosts = slaveHosts.filterProperty('componentName', "CLIENT").objectAt(0).hosts;
 
     // note: masterHosts has 'component' vs slaveHosts has 'componentName'
     var masterComponents = masterHosts.mapProperty('component').uniq();
@@ -962,9 +961,9 @@ App.WizardStep8Controller = Em.Controller.extend({
         var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName');
         this.registerHostsToComponent(hostNames, _slave.componentName);
       } else {
-        this.get('content.clients').forEach(function (_client) {
-          if (!_client.isInstalled) {
-            var hostNames = clientHosts.mapProperty('hostName').splice(0);
+        clients.forEach(function (_client) {
+
+            var hostNames = _slave.hosts.mapProperty('hostName');
             switch (_client.component_name) {
               case 'HDFS_CLIENT':
                 // install HDFS_CLIENT on HBASE_MASTER, HBASE_REGIONSERVER, and WEBHCAT_SERVER hosts
@@ -1013,8 +1012,19 @@ App.WizardStep8Controller = Em.Controller.extend({
                 break;
             }
             hostNames = hostNames.uniq();
+
+            if(_client.isInstalled){
+              //check whether clients are already installed on selected master hosts!!!
+              var installedHosts = _slave.hosts.filterProperty('isInstalled', true).mapProperty('hostName');
+              installedHosts.forEach(function(host){
+                if(hostNames.contains(host)){
+                  hostNames.splice(hostNames.indexOf(host), 1);
+                }
+              }, this);
+            }
+
             this.registerHostsToComponent(hostNames, _client.component_name);
-          }
+
         }, this);
       }
     }, this);

+ 3 - 1
ambari-web/app/mappers/runs_mapper.js

@@ -37,7 +37,9 @@ App.runsMapper = App.QuickDataMapper.create({
             item.targets.forEach(function(target) {
               r += '"' + target + '",';
             });
-            r = r.substr(0, r.length - 1);
+            if(item.targets.length){
+              r = r.substr(0, r.length - 1);
+            }
           } else {
             r += item.source;
           }

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

@@ -86,12 +86,22 @@ App.Host = DS.Model.extend({
    * Format diskUsage to float with 2 digits
    */
   diskUsageFormatted: function() {
+    if (isNaN(this.get('diskUsage')) || this.get('diskUsage') < 0) {
+      return 'Data Unavailable';
+    }
     var s = Math.round(this.get('diskUsage') * Math.pow(10, 2)) / Math.pow(10, 2);
     if (isNaN(s)) {
       s = 0;
     }
     return s + '%';
   }.property('diskUsage'),
+
+  diskInfoBar: function() {
+    if (isNaN(this.get('diskUsage')) || this.get('diskUsage') < 0) {
+      return this.get('diskUsageFormatted');
+    }
+    return this.get('diskUsedFormatted') + '/' + this.get('diskTotalFormatted') + ' (' + this.get('diskUsageFormatted') + ' used)';
+  }.property('diskUsedFormatted', 'diskTotalFormatted'),
   /**
    * formatted bytes to appropriate value
    */

+ 14 - 14
ambari-web/app/styles/application.less

@@ -220,6 +220,10 @@ h1 {
   text-align: left;
 }
 
+.popover {
+  z-index: 1050;
+}
+
 #installer, #add-host, #add-service {
   h2 {
     margin-top: 0;
@@ -1413,40 +1417,36 @@ a:focus {
       margin-top:-12px !important;
     }
   }
-  .health-status-started, .health-status-starting {
-    background-image: @status-live-marker;
+  .marker {
     background-repeat: no-repeat;
     display: inline-block;
     height: 13px;
     width: 13px;
   }
+  .health-status-started, .health-status-starting {
+    background-image: @status-live-marker;
+    .marker;
+  }
   .health-status-installed, .health-status-stopping {
     background-image: @status-dead-marker;
-    background-repeat: no-repeat;
-    display: inline-block;
-    height: 13px;
-    width: 13px;
+    .marker;
   }
 
   .health-status-LIVE {
     background-image: @status-live-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
+    .marker;
   }
   .health-status-DEAD {
     background-image: @status-dead-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
+    .marker;
   }
   .health-status-DEAD-ORANGE {
     background-image: @status-dead-orange-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
+    .marker;
   }
   .health-status-DEAD-YELLOW {
     background-image: @status-dead-yellow-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
+    .marker;
   }
   .back {
     display: block;

+ 3 - 0
ambari-web/app/templates/main/apps.hbs

@@ -27,6 +27,7 @@
       <td>Duration</td>
       <td>Oldest</td>
       <td>Most Recent</td>
+      <td></td>
     </tr>
     <tr class="avg-info">
       <td>{{view.avgData.jobs.avg}}</td>
@@ -35,6 +36,7 @@
       <td>{{view.avgData.duration.avg}}</td>
       <td>{{view.avgData.times.oldest}}</td>
       <td>{{view.avgData.times.youngest}}</td>
+      <td>Avg</td>
     </tr>
     <tr class="compare-info">
       <td>{{view.avgData.jobs.min}} / {{view.avgData.jobs.max}}</td>
@@ -43,6 +45,7 @@
       <td>{{view.avgData.duration.min}} / {{view.avgData.duration.max}}</td>
       <td></td>
       <td></td>
+      <td>Min / Max</td>
     </tr>
     </tbody>
   </table>

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

@@ -69,7 +69,7 @@
       <td>{{host.cpu}}</td>
       <td>{{host.memoryFormatted}}</td>
       <td>
-        <div class="progress progress-info" title="{{unbound host.diskUsedFormatted}} / {{unbound host.diskTotalFormatted}} ({{unbound host.diskUsageFormatted}} used)">
+        <div class="progress progress-info" title="{{unbound host.diskInfoBar}}">
           <div class="bar" {{bindAttr style="view.usageStyle"}}></div>
         </div>
       </td>

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

@@ -17,7 +17,7 @@
 }}
 
 <div id="host-details">
-  <div {{bindAttr class=":host-title view.content.healthClass"}}>{{unbound view.content.publicHostName}}</div>
+  <span {{bindAttr class="view.content.healthClass"}}></span><span class='host-title'>{{unbound view.content.publicHostName}}</span>
   <div><a href="javascript:void(null)" data-toggle="modal" {{action backToHostsList}}><i class="icon-arrow-left"></i>&nbsp;Back to Hosts</a></div>
 <!--   {{#if controller.isAdmin}} -->
 <!--   <div class="host-maintenance"> -->

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

@@ -47,7 +47,7 @@
         <div class="host-components">
           {{#each component in view.sortedComponents}}
           <div class="row-fluid">
-          {{#view view.ComponentView contentBinding="component"}}
+          {{#view view.ComponentView contentBinding="component" decommissionDataNodeHostNamesBinding="view.decommissionDataNodeHostNames"}}
             <div class="span8">
               <span {{bindAttr class="view.statusClass :components-health"}}></span>&nbsp;
               {{component.displayName}}&nbsp;/&nbsp;

+ 15 - 1
ambari-web/app/utils/graph.js

@@ -18,6 +18,19 @@
 
 
 module.exports = {
+  uniformSeries: function () {
+    var series_min_length = 100000000;
+    for (i=0; i<arguments.length; i++) {
+      if (arguments[i].length < series_min_length) {
+        series_min_length = arguments[i].length;
+      }
+    }
+    for (i=0; i<arguments.length; i++) {
+      if (arguments[i].length > series_min_length) {
+        arguments[i].length = series_min_length;
+      }
+    }
+  },
   drawJobTimeLine:function (map, shuffle, reduce, w, h, element, legend_id, timeline_id) {
     map = $.parseJSON(map);
     shuffle = $.parseJSON(shuffle);
@@ -26,7 +39,7 @@ module.exports = {
       console.warn('drawJobTimeLine');
       return;
     }
-
+    this.uniformSeries(map, reduce, shuffle);
     var graph = new Rickshaw.Graph({
       width:w,
       height:h,
@@ -108,6 +121,7 @@ module.exports = {
       console.warn('drawJobTasks');
       return;
     }
+    this.uniformSeries(mapNodeLocal, mapRackLocal, mapOffSwitch, reduceOffSwitch);
 
     var graph = new Rickshaw.Graph({
       width:w,

+ 7 - 3
ambari-web/app/views/common/chart/linear_time.js

@@ -281,6 +281,7 @@ App.ChartLinearTimeView = Ember.View.extend({
         if (this.checkSeries(seriesData)) {
           //if graph opened as modal popup
           var popup_path = $("#" + this.id + "-container" + this.get('popupSuffix'));
+          var graph_container = $("#" + this.id + "-container");
           if(popup_path.length) {
             popup_path.children().each(function () {
               $(this).children().remove();
@@ -288,12 +289,15 @@ App.ChartLinearTimeView = Ember.View.extend({
             this.set('isPopup', true);
           }
           else {
-            $("#" + this.id + "-container").children().each(function (index, value) {
+            graph_container.children().each(function (index, value) {
               $(value).children().remove();
             });
           }
-          this.draw(seriesData);
-          this.set('hasData', true);
+          // Check container exists (may be not, if we go to another page and wait while graphs loading)
+          if (graph_container.length) {
+            this.draw(seriesData);
+            this.set('hasData', true);
+          }
         }
         else {
           this.set('isReady', true);

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

@@ -374,7 +374,8 @@ App.MainAppsView = Em.View.extend({
         { "sType":"ambari-bandwidth" },
         null,
         { "sType":"ambari-datetime" }
-      ]
+      ],
+      "aaSorting": [[ 10, "desc" ]]
     }).css('visibility', 'visible');
     this.set('oTable', oTable);
     this.set('filtered', oTable.fnSettings().fnRecordsDisplay());

+ 10 - 2
ambari-web/app/views/main/dashboard/service/hbase.js

@@ -54,7 +54,11 @@ App.MainDashboardServiceHbaseView = App.MainDashboardServiceView.extend({
   masterStartedTime: function () {
     var uptime = this.get('service').get('masterStartTime');
     if (uptime && uptime > 0) {
-      var formatted = date.timingFormat((new Date().getTime() - uptime));
+      var diff = (new Date()).getTime() - uptime;
+      if (diff < 0) {
+        diff = 0;
+      }
+      var formatted = date.timingFormat(diff);
       return this.t('dashboard.services.uptime').format(formatted);
     }
     return this.t('services.service.summary.unknown');
@@ -63,7 +67,11 @@ App.MainDashboardServiceHbaseView = App.MainDashboardServiceView.extend({
   masterActivatedTime: function () {
     var uptime = this.get('service').get('masterActiveTime');
     if (uptime && uptime > 0) {
-      var formatted = date.timingFormat((new Date().getTime() - uptime));
+      var diff = (new Date()).getTime() - uptime;
+      if (diff < 0) {
+        diff = 0;
+      }
+      var formatted = date.timingFormat(diff);
       return this.t('dashboard.services.uptime').format(formatted);
     }
     return this.t('services.service.summary.unknown');

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

@@ -33,7 +33,11 @@ App.MainDashboardServiceHdfsView = App.MainDashboardServiceView.extend({
 
   nodeUptime: function () {
     var uptime = this.get('service').get('nameNodeStartTime');
-    var formatted = date.timingFormat((new Date().getTime() - uptime));
+    var diff = (new Date()).getTime() - uptime;
+    if (diff < 0) {
+      diff = 0;
+    }
+    var formatted = date.timingFormat(diff);
     return this.t('dashboard.services.uptime').format(formatted);
   }.property("service.nameNodeStartTime"),
 

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

@@ -33,7 +33,11 @@ App.MainDashboardServiceMapreduceView = App.MainDashboardServiceView.extend({
 
   jobTrackerUptime: function () {
     var uptime = this.get('service').get('jobTrackerStartTime');
-    var formatted = date.timingFormat((new Date().getTime() - uptime));
+    var diff = (new Date()).getTime() - uptime;
+    if (diff < 0) {
+      diff = 0;
+    }
+    var formatted = date.timingFormat(diff);
     return this.t('dashboard.services.uptime').format(formatted);
   }.property("service.jobTrackerStartTime"),
 

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

@@ -259,7 +259,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
       }
     }
     return svc;
-  }.property('controller.content.serviceName'),
+  }.property().volatile(),
 
   isHide:true,
   moreStatsView:Em.View.extend({