Updated Branches: refs/heads/trunk bae037a86 -> 2b6dd0427
AMBARI-3628. Restart indicators for services and hosts needed. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/incubator-ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ambari/commit/2b6dd042 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ambari/tree/2b6dd042 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ambari/diff/2b6dd042 Branch: refs/heads/trunk Commit: 2b6dd0427ae1795e0109dd1a7943261d8dfb6aca Parents: bae037a Author: Oleg Nechiporenko <[email protected]> Authored: Wed Oct 30 19:13:48 2013 +0200 Committer: Oleg Nechiporenko <[email protected]> Committed: Wed Oct 30 19:13:48 2013 +0200 ---------------------------------------------------------------------- .../assets/data/dashboard/HDP2/services.json | 5 ++ ambari-web/app/controllers/main/host/details.js | 7 +++ .../controllers/main/service/info/configs.js | 49 ++++++++++++++++++++ ambari-web/app/mappers/service_mapper.js | 1 + ambari-web/app/messages.js | 7 +++ ambari-web/app/models/host_component.js | 1 + ambari-web/app/models/service.js | 16 +++++-- .../app/templates/common/selectable_popup.hbs | 35 ++++++++++++++ ambari-web/app/templates/main/host/summary.hbs | 14 ++++++ .../app/templates/main/service/info/configs.hbs | 16 +++++-- ambari-web/app/views/main/host/summary.js | 8 ++++ .../app/views/main/service/info/configs.js | 17 ++++++- ambari-web/app/views/main/service/menu.js | 5 ++ 13 files changed, 173 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/assets/data/dashboard/HDP2/services.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/dashboard/HDP2/services.json b/ambari-web/app/assets/data/dashboard/HDP2/services.json index 3031a8e..dd41fbf 100644 --- a/ambari-web/app/assets/data/dashboard/HDP2/services.json +++ b/ambari-web/app/assets/data/dashboard/HDP2/services.json @@ -30,6 +30,7 @@ "service_name" : "GANGLIA", "stack_id" : "HDP-2.0.5", "state" : "STARTED", + "stale_configs": "true", "actual_configs" : { "capacity-scheduler" : { "tag" : "version1" @@ -93,6 +94,7 @@ "service_name" : "GANGLIA", "stack_id" : "HDP-2.0.5", "state" : "STARTED", + "stale_configs": "true", "actual_configs" : { "capacity-scheduler" : { "tag" : "version1" @@ -199,6 +201,7 @@ "desired_stack_id" : "HDP-2.0.5", "desired_state" : "STARTED", "ha_status" : "passive", + "stale_configs": "true", "host_name" : "dev01.hortonworks.com", "service_name" : "HBASE", "stack_id" : "HDP-2.0.5", @@ -884,6 +887,7 @@ "service_name" : "MAPREDUCE2", "stack_id" : "HDP-2.0.5", "state" : "STARTED", + "stale_configs": "true", "actual_configs" : { "capacity-scheduler" : { "tag" : "version1" @@ -953,6 +957,7 @@ "service_name" : "MAPREDUCE2", "stack_id" : "HDP-2.0.5", "state" : "INSTALLED", + "stale_configs": "true", "actual_configs" : { }, "configs" : { }, "desired_configs" : { } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/controllers/main/host/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js index 7304665..ef76e1a 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -801,5 +801,12 @@ App.MainHostDetailsController = Em.Controller.extend({ this.hide(); } }) + }, + + restartComponents: function() { + App.showConfirmationPopup(function() { + + }); } + }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/controllers/main/service/info/configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js index 88e1829..7cfecae 100644 --- a/ambari-web/app/controllers/main/service/info/configs.js +++ b/ambari-web/app/controllers/main/service/info/configs.js @@ -1545,5 +1545,54 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({ doCancel: function () { this.loadStep(); + }, + restartComponents: function() { + App.showConfirmationPopup(function() { + + }); + }, + showHostsShouldBeRestarted: function() { + var hosts = []; + for(var hostName in this.get('content.restartRequiredHostsAndComponents')) { + hosts.push(hostName); + } + hosts = hosts.join(', '); + this.showItemsShouldBeRestarted(hosts, Em.I18n.t('service.service.config.restartService.hostsShouldBeRestarted')); + }, + showComponentsShouldBeRestarted: function() { + var rhc = this.get('content.restartRequiredHostsAndComponents'); + var hostsComponets = []; + for(var hostName in rhc) { + rhc[hostName].forEach(function(hostComponent) { + hostsComponets.push(hostComponent); + }) + } + hostsComponets = hostsComponets.join(', '); + this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.componentsShouldBeRestarted')); + }, + + showItemsShouldBeRestarted: function(content, header) { + App.ModalPopup.show({ + content: content, + header: header, + bodyClass: Em.View.extend({ + templateName: require('templates/common/selectable_popup'), + textareaVisible: false, + textTrigger: function() { + this.set('textareaVisible', !this.get('textareaVisible')); + }, + putContentToTextarea: function() { + var content = this.get('parentView.content'); + if (this.get('textareaVisible')) { + var wrapper = $(".task-detail-log-maintext"); + $('.task-detail-log-clipboard').html(content).width(wrapper.width()).height(wrapper.height()); + Em.run.next(function() { + $('.task-detail-log-clipboard').select(); + }); + } + }.observes('textareaVisible') + }), + secondary: null + }); } }); http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/mappers/service_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/service_mapper.js b/ambari-web/app/mappers/service_mapper.js index fc1c90b..1106da8 100644 --- a/ambari-web/app/mappers/service_mapper.js +++ b/ambari-web/app/mappers/service_mapper.js @@ -166,6 +166,7 @@ App.servicesMapper = App.QuickDataMapper.create({ component_name: 'HostRoles.component_name', ha_status: 'HostRoles.ha_status', host_id: 'HostRoles.host_name', + stale_configs: 'HostRoles.stale_configs', $service_id: 'none' /* will be set outside of parse function */ }, http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index c016572..6f441d4 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -35,6 +35,7 @@ Em.I18n.translations = { 'to':'To', 'ok':'OK', 'as':'as', + 'on':'on', 'any': 'Any', 'more':'more', 'yes':'Yes', @@ -1065,6 +1066,10 @@ Em.I18n.translations = { 'services.service.config.saved':'Saved Configuration Changes', 'services.service.config.notSaved':'Unable to Save Configuration Changes', 'services.service.config.restartService.TooltipMessage':'<b>Restart Service</b><br>Stale configuration used by {0} components on {1} hosts:{2}', + 'services.service.config.restartService.needToRestart':'<strong>Restart Service</strong> ', + 'services.service.config.restartService.needToRestartEnd':'should be restated', + 'service.service.config.restartService.hostsShouldBeRestarted':'Hosts should be restarted', + 'service.service.config.restartService.componentsShouldBeRestarted':'Components should be restarted', 'services.service.config.saved.message':'Service configuration changes saved successfully.', 'services.service.config.msgServiceStop':'Could not save configuration changes. Please stop the service first. You will be able to save configuration changes after all of its components are stopped.', 'services.service.config.msgHDFSMapRServiceStop':'Could not save configuration changes. Please stop both HDFS and MapReduce first. You will be able to save configuration changes after all HDFS and MapReduce components are stopped.', @@ -1263,6 +1268,8 @@ Em.I18n.translations = { 'hosts.host.summary.agentHeartbeat':'Agent <br/> Heartbeat', 'hosts.host.summary.hostMetrics':'Host Metrics', + 'hosts.host.details.needToRestart':'Host needs {0} components restarted', + 'hosts.host.details.needToRestart.button':'Restart components', 'hosts.host.details.deleteHost':'Delete Host', 'hosts.host.details.startAllComponents':'Start All Components', 'hosts.host.details.stopAllComponents':'Stop All Components', http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/models/host_component.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js index 3997420..0121d53 100644 --- a/ambari-web/app/models/host_component.js +++ b/ambari-web/app/models/host_component.js @@ -22,6 +22,7 @@ App.HostComponent = DS.Model.extend({ workStatus: DS.attr('string'), componentName: DS.attr('string'), haStatus: DS.attr('string'), + staleConfigs: DS.attr('boolean'), host: DS.belongsTo('App.Host'), service: DS.belongsTo('App.Service'), isClient:function () { http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/models/service.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js index b19b34e..a80a1c4 100644 --- a/ambari-web/app/models/service.js +++ b/ambari-web/app/models/service.js @@ -107,10 +107,18 @@ App.Service = DS.Model.extend({ * properties, which need to be checked with map. */ isRestartRequired: function () { - var restartRequired = false; - var restartRequiredHostsAndComponents = {}; - this.set('restartRequiredHostsAndComponents', restartRequiredHostsAndComponents); - return restartRequired; + var rhc = this.get('hostComponents').filterProperty('staleConfigs', true); + var hc = {}; + rhc.forEach(function(_rhc) { + var hostName = _rhc.get('host.publicHostName'); + if (!hc[hostName]) { + hc[hostName] = []; + } + hc[hostName].push(_rhc.get('displayName')); + }); + this.set('restartRequiredHostsAndComponents', hc); + return (rhc.length>0); + }.property('serviceName', 'hostComponents'), /** http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/templates/common/selectable_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/selectable_popup.hbs b/ambari-web/app/templates/common/selectable_popup.hbs new file mode 100644 index 0000000..4426d2c --- /dev/null +++ b/ambari-web/app/templates/common/selectable_popup.hbs @@ -0,0 +1,35 @@ +{{! +* 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> + <div class="task-top-wrap"> + <div class="task-detail-ico-wrap"> + <a href="#" title="Click to Copy" {{action "textTrigger"}} class="task-detail-copy"><i class="icon-copy"></i> {{t common.copy}}</a> + </div> + </div> + <div class="task-detail-log-info"> + <div class="content-area" > + <div {{bindAttr class="view.textareaVisible::hidden :task-detail-log-clipboard-wrap"}}> + <textarea class="task-detail-log-clipboard"></textarea> + </div> + <div {{bindAttr class="view.textareaVisible:hidden :task-detail-log-maintext"}}> + {{content}} + </div> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/templates/main/host/summary.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host/summary.hbs b/ambari-web/app/templates/main/host/summary.hbs index 6328f63..5626f06 100644 --- a/ambari-web/app/templates/main/host/summary.hbs +++ b/ambari-web/app/templates/main/host/summary.hbs @@ -26,6 +26,16 @@ </div> <div class="host-components"> {{#if view.sortedComponents.length}} + + {{#if view.needToRestartComponentsCount}} + <div class="alert alert-warning clearfix"> + <i class="icon-refresh"></i> {{view.needToRestartMessage}} + <button class="btn btn-warning restart-components pull-right" {{action restartComponents target="controller"}}> + {{t hosts.host.details.needToRestart.button}} + </button> + </div> + {{/if}} + {{#each component in view.sortedComponents}} <div class="row-fluid"> {{#view view.ComponentView contentBinding="component" decommissionDataNodeHostNamesBinding="view.decommissionDataNodeHostNames"}} @@ -46,6 +56,10 @@ {{/if}} / <a href="#" {{action routeToService component.service target="controller" }}>{{component.service.displayName}}</a> + + {{#if component.staleConfigs}} + <i class="text-warning icon-refresh"></i> + {{/if}} </div> <div class="span5"> {{#if App.isAdmin}} http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/templates/main/service/info/configs.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/info/configs.hbs b/ambari-web/app/templates/main/service/info/configs.hbs index a9b22e2..3adc914 100644 --- a/ambari-web/app/templates/main/service/info/configs.hbs +++ b/ambari-web/app/templates/main/service/info/configs.hbs @@ -19,9 +19,19 @@ <div id="serviceConfig"> {{#if dataIsLoaded}} {{#if App.supports.hostOverrides}} - <div class="pull-right"> - {{view App.FilterComboboxView filterBinding="controller.filter" columnsBinding="controller.filterColumns" }} - </div> + {{#if controller.content.isRestartRequired}} + <div> + <div class="alert alert-warning clearfix"> + <i class="icon-refresh"></i> {{{view.needToRestartMessage}}} <a href="#" {{action showComponentsShouldBeRestarted target="controller"}}>{{view.componentsCount}} {{t common.components}}</a> {{t on}} <a href="#" {{action showHostsShouldBeRestarted target="controller"}}>{{view.hostsCount}} {{t dashboard.services.hosts}}</a> {{t services.service.config.restartService.needToRestartEnd}} + <button class="btn btn-warning restart-components pull-right" {{action restartComponents target="controller"}}> + {{t hosts.host.details.needToRestart.button}} + </button> + </div> + </div> + {{/if}} + <div class="pull-right"> + {{view App.FilterComboboxView filterBinding="controller.filter" columnsBinding="controller.filterColumns" }} + </div> {{/if}} <div class="clearfix"></div> {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns"}} http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/views/main/host/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js index 1826519..b19e41a 100644 --- a/ambari-web/app/views/main/host/summary.js +++ b/ambari-web/app/views/main/host/summary.js @@ -32,6 +32,14 @@ App.MainHostSummaryView = Em.View.extend({ window.open(gangliaMobileUrl); }, + needToRestartComponentsCount: function() { + return this.get('sortedComponents').filterProperty('staleConfigs', true).length; + }.property('sortedComponents'), + + needToRestartMessage: function() { + return Em.I18n.t('hosts.host.details.needToRestart').format(this.get('needToRestartComponentsCount')); + }.property(), + /** * @type: [{String}] */ http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/views/main/service/info/configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/configs.js b/ambari-web/app/views/main/service/info/configs.js index 563d87c..a7abdff 100644 --- a/ambari-web/app/views/main/service/info/configs.js +++ b/ambari-web/app/views/main/service/info/configs.js @@ -23,5 +23,20 @@ App.MainServiceInfoConfigsView = Em.View.extend({ didInsertElement: function () { var controller = this.get('controller'); controller.loadStep(); - } + }, + + componentsCount: null, + hostsCount: null, + + calculateCounts: function() { + var hc = this.get('controller.content.restartRequiredHostsAndComponents'); + var hostsCount = 0; + var componentsCount = 0; + for (var host in hc) { + hostsCount++; + componentsCount += hc[host].length; + } + this.set('componentsCount', componentsCount); + this.set('hostsCount', hostsCount); + }.observes('controller.content.restartRequiredHostsAndComponents') }); http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/2b6dd042/ambari-web/app/views/main/service/menu.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/menu.js b/ambari-web/app/views/main/service/menu.js index 1d1f328..a71c72c 100644 --- a/ambari-web/app/views/main/service/menu.js +++ b/ambari-web/app/views/main/service/menu.js @@ -86,6 +86,11 @@ App.MainServiceMenuView = Em.CollectionView.extend({ classNames:["nav", "nav-list", "nav-services"], itemViewClass:Em.View.extend({ + + shouldBeRestarted: function() { + return this.get('content.hostComponents').someProperty('staleConfigs', true); + }.property('[email protected]'), + classNameBindings:["active", "clients"], active:function () { return this.get('content.id') == this.get('parentView.activeServiceId') ? 'active' : '';
