details.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var batchUtils = require('utils/batch_scheduled_requests');
  20. App.MainHostDetailsController = Em.Controller.extend({
  21. name: 'mainHostDetailsController',
  22. content: null,
  23. isFromHosts: false,
  24. /**
  25. * path to page visited before
  26. */
  27. referer: '',
  28. /**
  29. * open dashboard page
  30. */
  31. routeHome: function () {
  32. App.router.transitionTo('main.dashboard');
  33. },
  34. /**
  35. * open summary page of the selected service
  36. * @param event
  37. */
  38. routeToService: function(event){
  39. var service = event.context;
  40. App.router.transitionTo('main.services.service.summary',service);
  41. },
  42. serviceActiveComponents: function() {
  43. return this.get('content.hostComponents').filterProperty('service.isInPassive',false);
  44. }.property('content.hostComponents'),
  45. serviceNonClientActiveComponents: function() {
  46. return this.get('serviceActiveComponents').filterProperty('isClient',false);
  47. }.property('serviceActiveComponents'),
  48. /**
  49. * Send specific command to server
  50. * @param url
  51. * @param _method
  52. * @param postData
  53. * @param callback
  54. */
  55. sendCommandToServer : function(url, postData, _method, callback){
  56. var url = (App.testMode) ?
  57. '/data/wizard/deploy/poll_1.json' : //content is the same as ours
  58. App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  59. var method = App.testMode ? 'GET' : _method;
  60. $.ajax({
  61. type: method,
  62. url: url,
  63. data: JSON.stringify(postData),
  64. dataType: 'json',
  65. timeout: App.timeout,
  66. success: function(data){
  67. if(data && data.Requests){
  68. callback(data.Requests.id);
  69. } else{
  70. callback(null);
  71. console.log('cannot get request id from ', data);
  72. }
  73. },
  74. error: function (request, ajaxOptions, error) {
  75. //do something
  76. console.log('error on change component host status');
  77. App.ajax.defaultErrorHandler(request, url, method);
  78. },
  79. statusCode: require('data/statusCodes')
  80. });
  81. },
  82. /**
  83. * send command to server to start selected host component
  84. * @param event
  85. */
  86. startComponent: function (event) {
  87. var self = this;
  88. App.showConfirmationPopup(function() {
  89. var component = event.context;
  90. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  91. self.sendStartComponentCommand(component, context);
  92. });
  93. },
  94. /**
  95. * PUTs a command to server to start a component. If no
  96. * specific component is provided, all components are started.
  97. * @param component When <code>null</code> all startable components are started.
  98. * @param context Context under which this command is beign sent.
  99. */
  100. sendStartComponentCommand: function(components, context) {
  101. var url = Em.isArray(components) ?
  102. '/hosts/' + this.get('content.hostName') + '/host_components' :
  103. '/hosts/' + this.get('content.hostName') + '/host_components/' + components.get('componentName').toUpperCase();
  104. var dataToSend = {
  105. RequestInfo : {
  106. "context" : context
  107. },
  108. Body:{
  109. HostRoles:{
  110. state: 'STARTED'
  111. }
  112. }
  113. };
  114. if (Em.isArray(components)) {
  115. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + components.mapProperty('componentName').join(',') + ")";
  116. }
  117. this.sendCommandToServer(url, dataToSend, 'PUT',
  118. function(requestId){
  119. if(!requestId){
  120. return;
  121. }
  122. console.log('Send request for STARTING successfully');
  123. if (App.testMode) {
  124. if(Em.isArray(components)){
  125. var allComponents = this.get('content.hostComponents');
  126. allComponents.forEach(function(component){
  127. component.set('workStatus', App.HostComponentStatus.stopping);
  128. setTimeout(function(){
  129. component.set('workStatus', App.HostComponentStatus.stopped);
  130. },App.testModeDelayForActions);
  131. });
  132. } else {
  133. components.set('workStatus', App.HostComponentStatus.starting);
  134. setTimeout(function(){
  135. components.set('workStatus', App.HostComponentStatus.started);
  136. },App.testModeDelayForActions);
  137. }
  138. } else {
  139. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  140. }
  141. // load data (if we need to show this background operations popup) from persist
  142. App.router.get('applicationController').dataLoading().done(function (initValue) {
  143. if (initValue) {
  144. App.router.get('backgroundOperationsController').showPopup();
  145. }
  146. });
  147. });
  148. },
  149. /**
  150. * send command to server to delete selected host component
  151. *
  152. */
  153. deleteComponent: function (event) {
  154. var self = this;
  155. var component = event.context;
  156. var componentName = component.get('componentName');
  157. var displayName = component.get('displayName');
  158. var isLastComponent = (App.HostComponent.find().filterProperty('componentName', componentName).get('length') === 1);
  159. App.ModalPopup.show({
  160. header: Em.I18n.t('popup.confirmation.commonHeader'),
  161. primary: Em.I18n.t('hosts.host.deleteComponent.popup.confirm'),
  162. bodyClass: Ember.View.extend({
  163. templateName: require('templates/main/host/details/deleteComponentPopup')
  164. }),
  165. isChecked: false,
  166. disablePrimary: function () {
  167. return !this.get('isChecked');
  168. }.property('isChecked'),
  169. lastComponent: function() {
  170. if (isLastComponent) {
  171. this.set('isChecked', false);
  172. return true;
  173. } else {
  174. this.set('isChecked', true);
  175. return false;
  176. }
  177. }.property(),
  178. lastComponentError: Em.View.extend({
  179. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  180. }),
  181. restartNagiosMsg: Em.View.extend({
  182. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.msg2').format(displayName))
  183. }),
  184. deleteComponentMsg: function() {
  185. return Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(displayName);
  186. }.property(),
  187. onPrimary: function () {
  188. self._doDeleteHostComponent(component);
  189. self.set('redrawComponents', true);
  190. this.hide();
  191. }
  192. });
  193. },
  194. /**
  195. * Trigger to reset list of master/slaves components on the view
  196. * @type {bool}
  197. */
  198. redrawComponents: false,
  199. /**
  200. * Deletes the given host component, or all host components.
  201. *
  202. * @param component When <code>null</code> all host components are deleted.
  203. * @return <code>null</code> when components get deleted.
  204. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  205. * when components failed to get deleted.
  206. */
  207. _doDeleteHostComponent: function(component) {
  208. var url = component !== null ?
  209. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  210. '/hosts/' + this.get('content.hostName') + '/host_components';
  211. url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  212. var deleted = null;
  213. $.ajax({
  214. type: 'DELETE',
  215. url: url,
  216. timeout: App.timeout,
  217. async: false,
  218. success: function (data) {
  219. deleted = null;
  220. },
  221. error: function (xhr, textStatus, errorThrown) {
  222. console.log('Error deleting host component');
  223. console.log(textStatus);
  224. console.log(errorThrown);
  225. deleted = {xhr: xhr, url: url, method: 'DELETE'};
  226. },
  227. statusCode: require('data/statusCodes')
  228. });
  229. return deleted;
  230. },
  231. /**
  232. * send command to server to upgrade selected host component
  233. * @param event
  234. */
  235. upgradeComponent: function (event) {
  236. var self = this;
  237. var component = event.context;
  238. App.showConfirmationPopup(function() {
  239. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(),{
  240. RequestInfo : {
  241. "context" : Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  242. },
  243. Body:{
  244. HostRoles:{
  245. stack_id: 'HDP-1.2.2',
  246. state: 'INSTALLED'
  247. }
  248. }
  249. }, 'PUT',
  250. function(requestId){
  251. if(!requestId){
  252. return;
  253. }
  254. console.log('Send request for UPGRADE successfully');
  255. if (App.testMode) {
  256. component.set('workStatus', App.HostComponentStatus.starting);
  257. setTimeout(function(){
  258. component.set('workStatus', App.HostComponentStatus.started);
  259. },App.testModeDelayForActions);
  260. } else {
  261. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  262. }
  263. // load data (if we need to show this background operations popup) from persist
  264. App.router.get('applicationController').dataLoading().done(function (initValue) {
  265. if (initValue) {
  266. App.router.get('backgroundOperationsController').showPopup();
  267. }
  268. });
  269. });
  270. });
  271. },
  272. /**
  273. * send command to server to stop selected host component
  274. * @param event
  275. */
  276. stopComponent: function (event) {
  277. var self = this;
  278. App.showConfirmationPopup(function() {
  279. var component = event.context;
  280. var context = Em.I18n.t('requestInfo.stopHostComponent')+ " " + component.get('displayName');
  281. self.sendStopComponentCommand(component, context);
  282. });
  283. },
  284. /**
  285. * PUTs a command to server to stop a component. If no
  286. * specific component is provided, all components are stopped.
  287. * @param component When <code>null</code> all components are stopped.
  288. * @param context Context under which this command is beign sent.
  289. */
  290. sendStopComponentCommand: function(components, context){
  291. var url = Em.isArray(components) ?
  292. '/hosts/' + this.get('content.hostName') + '/host_components' :
  293. '/hosts/' + this.get('content.hostName') + '/host_components/' + components.get('componentName').toUpperCase();
  294. var dataToSend = {
  295. RequestInfo : {
  296. "context" : context
  297. },
  298. Body:{
  299. HostRoles:{
  300. state: 'INSTALLED'
  301. }
  302. }
  303. };
  304. if (Em.isArray(components)) {
  305. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + components.mapProperty('componentName').join(',') + ")";
  306. }
  307. this.sendCommandToServer( url, dataToSend, 'PUT',
  308. function(requestId){
  309. if(!requestId){
  310. return;
  311. }
  312. console.log('Send request for STOPPING successfully');
  313. if (App.testMode) {
  314. if(Em.isArray(components)){
  315. components.forEach(function(component){
  316. component.set('workStatus', App.HostComponentStatus.stopping);
  317. setTimeout(function(){
  318. component.set('workStatus', App.HostComponentStatus.stopped);
  319. },App.testModeDelayForActions);
  320. });
  321. } else {
  322. components.set('workStatus', App.HostComponentStatus.stopping);
  323. setTimeout(function(){
  324. components.set('workStatus', App.HostComponentStatus.stopped);
  325. },App.testModeDelayForActions);
  326. }
  327. } else {
  328. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  329. }
  330. // load data (if we need to show this background operations popup) from persist
  331. App.router.get('applicationController').dataLoading().done(function (initValue) {
  332. if (initValue) {
  333. App.router.get('backgroundOperationsController').showPopup();
  334. }
  335. });
  336. });
  337. },
  338. restartComponent: function(event) {
  339. var self = this;
  340. var component = event.context;
  341. App.showConfirmationPopup(function(){
  342. batchUtils.restartHostComponents([component], Em.I18n.t('rollingrestart.context.selectedComponentOnSelectedHost').format(component.get('displayName')));
  343. });
  344. },
  345. /**
  346. * send command to server to install selected host component
  347. * @param event
  348. */
  349. addComponent: function (event) {
  350. var self = this;
  351. var component = event.context;
  352. var componentName = component.get('componentName').toUpperCase().toString();
  353. var subComponentNames = component.get('subComponentNames');
  354. var displayName = component.get('displayName');
  355. var securityEnabled = App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus();
  356. if (componentName === 'ZOOKEEPER_SERVER') {
  357. App.showConfirmationPopup(function() {
  358. self.primary(component);
  359. }, Em.I18n.t('hosts.host.addComponent.addZooKeeper'));
  360. }
  361. else {
  362. if (securityEnabled && component.get('componentName') !== 'CLIENTS') {
  363. App.showConfirmationPopup(function() {
  364. self.primary(component);
  365. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName,self.get('content.hostName')));
  366. }
  367. else {
  368. var dn = displayName;
  369. if (subComponentNames !== null && subComponentNames.length > 0) {
  370. var dns = [];
  371. subComponentNames.forEach(function(scn){
  372. dns.push(App.format.role(scn));
  373. });
  374. dn += " ("+dns.join(", ")+")";
  375. }
  376. App.ModalPopup.show({
  377. primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'),
  378. header: Em.I18n.t('popup.confirmation.commonHeader'),
  379. addComponentMsg: function() {
  380. return Em.I18n.t('hosts.host.addComponent.msg').format(dn);
  381. }.property(),
  382. bodyClass: Ember.View.extend({
  383. templateName: require('templates/main/host/details/addComponentPopup')
  384. }),
  385. restartNagiosMsg : Em.View.extend({
  386. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(dn))
  387. }),
  388. onPrimary: function () {
  389. this.hide();
  390. if (component.get('componentName') === 'CLIENTS') {
  391. // Clients component has many sub-components which
  392. // need to be installed.
  393. var scs = component.get('subComponentNames');
  394. scs.forEach(function (sc, index) {
  395. var c = Em.Object.create({
  396. displayName: App.format.role(sc),
  397. componentName: sc
  398. });
  399. self.primary(c, scs.length - index === 1);
  400. });
  401. } else {
  402. self.primary(component, true);
  403. }
  404. }
  405. });
  406. }
  407. }
  408. },
  409. primary: function(component, showPopup) {
  410. var self = this;
  411. var componentName = component.get('componentName').toUpperCase().toString();
  412. var displayName = component.get('displayName');
  413. self.sendCommandToServer('/hosts?Hosts/host_name=' + self.get('content.hostName'), {
  414. RequestInfo: {
  415. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  416. },
  417. Body: {
  418. host_components: [
  419. {
  420. HostRoles: {
  421. component_name: componentName
  422. }
  423. }
  424. ]
  425. }
  426. },
  427. 'POST',
  428. function (requestId) {
  429. console.log('Send request for ADDING NEW COMPONENT successfully');
  430. self.sendCommandToServer('/host_components?HostRoles/host_name=' + self.get('content.hostName') + '\&HostRoles/component_name=' + componentName + '\&HostRoles/state=INIT', {
  431. RequestInfo: {
  432. "context": Em.I18n.t('requestInfo.installNewHostComponent') + " " + displayName
  433. },
  434. Body: {
  435. HostRoles: {
  436. state: 'INSTALLED'
  437. }
  438. }
  439. },
  440. 'PUT',
  441. function (requestId) {
  442. if (!requestId) {
  443. return;
  444. }
  445. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  446. if (App.testMode) {
  447. component.set('workStatus', App.HostComponentStatus.installing);
  448. setTimeout(function () {
  449. component.set('workStatus', App.HostComponentStatus.stopped);
  450. }, App.testModeDelayForActions);
  451. } else {
  452. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  453. }
  454. // load data (if we need to show this background operations popup) from persist
  455. App.router.get('applicationController').dataLoading().done(function (initValue) {
  456. if (initValue) {
  457. App.router.get('backgroundOperationsController').showPopup();
  458. }
  459. if (componentName === 'ZOOKEEPER_SERVER') {
  460. self.set('zkRequestId', requestId);
  461. self.addObserver('App.router.backgroundOperationsController.serviceTimestamp', self, self.checkZkConfigs);
  462. self.checkZkConfigs();
  463. }
  464. });
  465. });
  466. });
  467. },
  468. /**
  469. * Load tags
  470. */
  471. checkZkConfigs: function() {
  472. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId'));
  473. if (!bg) return;
  474. if (!bg.get('isRunning')) {
  475. this.loadConfigs();
  476. }
  477. },
  478. loadConfigs: function() {
  479. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs);
  480. App.ajax.send({
  481. name: 'config.tags',
  482. sender: this,
  483. success: 'loadConfigsSuccessCallback'
  484. });
  485. },
  486. /**
  487. * Load needed configs
  488. * @param data
  489. */
  490. loadConfigsSuccessCallback: function(data) {
  491. var urlParams = [];
  492. if (App.get('isHaEnabled')) {
  493. urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
  494. }
  495. if (App.Service.find().someProperty('serviceName', 'HBASE')) {
  496. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  497. }
  498. if (App.Service.find().someProperty('serviceName', 'HIVE')) {
  499. urlParams.push('(type=webhcat-site&tag=' + data.Clusters.desired_configs['webhcat-site'].tag + ')');
  500. }
  501. if (App.Service.find().someProperty('serviceName', 'STORM')) {
  502. urlParams.push('(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')');
  503. }
  504. if (!urlParams.length) {
  505. return;
  506. }
  507. App.ajax.send({
  508. name: 'reassign.load_configs',
  509. sender: this,
  510. data: {
  511. urlParams: urlParams.join('|')
  512. },
  513. success: 'setNewZkConfigs'
  514. });
  515. },
  516. /**
  517. * Set new values for some configs (based on available ZooKeeper Servers)
  518. * @param data
  519. */
  520. setNewZkConfigs: function(data) {
  521. var configs = [];
  522. data.items.forEach(function (item) {
  523. configs[item.type] = item.properties;
  524. }, this);
  525. var zks = this.getZkServerHosts();
  526. var zks_with_port = '';
  527. zks.forEach(function(zk) {
  528. zks_with_port += zk + ':2181,';
  529. });
  530. zks_with_port = zks_with_port.slice(0,-1);
  531. if (App.get('isHaEnabled')) {
  532. configs['core-site']['ha.zookeeper.quorum'] = zks_with_port;
  533. }
  534. if (configs['hbase-site']) {
  535. configs['hbase-site']['hbase.zookeeper.quorum'] = zks.join(',');
  536. }
  537. if (configs['webhcat-site']) {
  538. configs['webhcat-site']['templeton.zookeeper.hosts'] = zks_with_port;
  539. }
  540. if (configs['storm-site']) {
  541. configs['storm-site']['storm.zookeeper.servers'] = JSON.stringify(zks).replace(/"/g, "'");
  542. }
  543. for (var site in configs) {
  544. if (!configs.hasOwnProperty(site)) continue;
  545. App.ajax.send({
  546. name: 'reassign.save_configs',
  547. sender: this,
  548. data: {
  549. siteName: site,
  550. properties: configs[site]
  551. }
  552. });
  553. }
  554. },
  555. /**
  556. * Is deleteHost action id fired
  557. */
  558. fromDeleteHost: false,
  559. getZkServerHosts: function() {
  560. var zks = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('host.hostName');
  561. if (this.get('fromDeleteHost')) {
  562. this.set('fromDeleteHost', false);
  563. return zks.without(this.get('content.hostName'));
  564. }
  565. return zks;
  566. },
  567. /**
  568. * send command to server to install selected host component
  569. * @param event
  570. * @param context
  571. */
  572. installComponent: function (event, context) {
  573. var self = this;
  574. var component = event.context;
  575. var componentName = component.get('componentName').toUpperCase().toString();
  576. var displayName = component.get('displayName');
  577. App.ModalPopup.show({
  578. primary: Em.I18n.t('hosts.host.installComponent.popup.confirm'),
  579. header: Em.I18n.t('popup.confirmation.commonHeader'),
  580. installComponentMessage: function(){
  581. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  582. }.property(),
  583. restartNagiosMsg : Em.View.extend({
  584. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(displayName))
  585. }),
  586. bodyClass: Ember.View.extend({
  587. templateName: require('templates/main/host/details/installComponentPopup')
  588. }),
  589. onPrimary: function () {
  590. this.hide();
  591. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(), {
  592. RequestInfo: {
  593. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  594. },
  595. Body: {
  596. HostRoles: {
  597. state: 'INSTALLED'
  598. }
  599. }
  600. },
  601. 'PUT',
  602. function (requestId) {
  603. if (!requestId) {
  604. return;
  605. }
  606. console.log('Send request for REINSTALL COMPONENT successfully');
  607. if (App.testMode) {
  608. component.set('workStatus', App.HostComponentStatus.installing);
  609. setTimeout(function () {
  610. component.set('workStatus', App.HostComponentStatus.stopped);
  611. }, App.testModeDelayForActions);
  612. } else {
  613. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  614. }
  615. // load data (if we need to show this background operations popup) from persist
  616. App.router.get('applicationController').dataLoading().done(function (initValue) {
  617. if (initValue) {
  618. App.router.get('backgroundOperationsController').showPopup();
  619. }
  620. });
  621. });
  622. }
  623. });
  624. },
  625. /**
  626. * send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
  627. * @param component
  628. */
  629. decommission: function(component){
  630. var self = this;
  631. App.showConfirmationPopup(function(){
  632. var svcName = component.get('service.serviceName');
  633. var hostName = self.get('content.hostName');
  634. // HDFS service, decommission DataNode
  635. if (svcName === "HDFS") {
  636. self.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
  637. }
  638. // YARN service, decommission NodeManager
  639. if (svcName === "YARN") {
  640. self.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  641. }
  642. // MAPREDUCE service, decommission TaskTracker
  643. if (svcName === "MAPREDUCE") {
  644. self.doDecommission(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  645. }
  646. // HBASE service, decommission RegionServer
  647. if (svcName === "HBASE") {
  648. self.warnBeforeDecommission(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  649. }
  650. // load data (if we need to show this background operations popup) from persist
  651. App.router.get('applicationController').dataLoading().done(function (initValue) {
  652. if (initValue) {
  653. App.router.get('backgroundOperationsController').showPopup();
  654. }
  655. });
  656. });
  657. },
  658. /**
  659. * send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
  660. * @param component
  661. */
  662. recommission: function(component){
  663. var self = this;
  664. App.showConfirmationPopup(function(){
  665. var svcName = component.get('service.serviceName');
  666. var hostName = self.get('content.hostName');
  667. // HDFS service, Recommission datanode
  668. if (svcName === "HDFS") {
  669. self.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE");
  670. }
  671. // YARN service, Recommission nodeManager
  672. if (svcName === "YARN") {
  673. self.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  674. }
  675. // MAPREDUCE service, Recommission taskTracker
  676. if (svcName === "MAPREDUCE") {
  677. self.doRecommissionAndRestart(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  678. }
  679. // HBASE service, Recommission RegionServer
  680. if (svcName === "HBASE") {
  681. self.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  682. }
  683. // load data (if we need to show this background operations popup) from persist
  684. App.router.get('applicationController').dataLoading().done(function (initValue) {
  685. if (initValue) {
  686. App.router.get('backgroundOperationsController').showPopup();
  687. }
  688. });
  689. });
  690. },
  691. /**
  692. * Performs Decommission (for DN, TT and NM)
  693. */
  694. doDecommission: function(hostName, serviceName, componentName, slaveType){
  695. var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
  696. var context = Em.I18n.t(contextNameString);
  697. App.ajax.send({
  698. name: 'host.host_component.decommission_slave',
  699. sender: this,
  700. data: {
  701. context: context,
  702. command: 'DECOMMISSION',
  703. hostName: hostName,
  704. serviceName: serviceName ,
  705. componentName: componentName,
  706. slaveType: slaveType
  707. },
  708. success: 'decommissionSuccessCallback',
  709. error: 'decommissionErrorCallback'
  710. });
  711. },
  712. /**
  713. * Recomends user to put component in MM before decommision (for HBASE only)
  714. * @method warnBeforeDecommission
  715. * @param {string[]} hostNames - list of host when run from bulk operations or current host
  716. * @param {string} serviceName - serviceName
  717. * @param {string} componentName - master compoent name
  718. * @param {string} slaveType - slave component name
  719. */
  720. warnBeforeDecommission: function(hostNames, serviceName, componentName, slaveType) {
  721. if (this.get('content.hostComponents').findProperty('componentName', componentName).get('passiveState') == "OFF") {
  722. App.ModalPopup.show({
  723. header: Em.I18n.t('common.warning'),
  724. message: function(){
  725. return Em.I18n.t('hostPopup.reccomendation.beforeDecommission').format(App.format.components[componentName]);
  726. }.property(),
  727. bodyClass: Ember.View.extend({
  728. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  729. }),
  730. secondary: false
  731. });
  732. } else {
  733. this.doDecommissionRegionServer(hostNames, serviceName, componentName, slaveType);
  734. }
  735. },
  736. /**
  737. * Performs Decommission (for RegionServer)
  738. * @method doDecommissionRegionServer
  739. * @param {string[]} hostNames - list of host when run from bulk operations or current host
  740. * @param {string} serviceName - serviceName
  741. * @param {string} componentName - master compoent name
  742. * @param {string} slaveType - slave component name
  743. */
  744. doDecommissionRegionServer: function(hostNames, serviceName, componentName, slaveType){
  745. App.ajax.send({
  746. name: 'host.host_component.recommission_and_restart',
  747. sender: this,
  748. data: {
  749. intervalTimeSeconds: 1,
  750. tolerateSize : 0,
  751. batches:[
  752. {
  753. "order_id" : 1,
  754. "type" : "POST",
  755. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  756. "RequestBodyInfo" : {
  757. "RequestInfo" : {
  758. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  759. "command" : "DECOMMISSION",
  760. "parameters" : {
  761. "slave_type": slaveType,
  762. "excluded_hosts": hostNames
  763. }
  764. },
  765. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  766. }
  767. },
  768. {
  769. "order_id": 2,
  770. "type": "PUT",
  771. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  772. "RequestBodyInfo" : {
  773. "RequestInfo" : {
  774. context: Em.I18n.t('hosts.host.regionserver.decommission.batch2'),
  775. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  776. },
  777. "Body": {
  778. HostRoles: {
  779. state: "INSTALLED"
  780. }
  781. }
  782. }
  783. },
  784. {
  785. "order_id" : 3,
  786. "type" : "POST",
  787. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  788. "RequestBodyInfo" : {
  789. "RequestInfo" : {
  790. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  791. "command" : "DECOMMISSION",
  792. "service_name" : serviceName,
  793. "component_name" : componentName,
  794. "parameters" : {
  795. "slave_type": slaveType,
  796. "excluded_hosts": hostNames,
  797. "mark_draining_only": "true"
  798. }
  799. }
  800. }
  801. }
  802. ]
  803. },
  804. success: 'decommissionSuccessCallback',
  805. error: 'decommissionErrorCallback'
  806. });
  807. },
  808. decommissionErrorCallback: function (request, ajaxOptions, error) {
  809. console.log('ERROR: '+ error);
  810. },
  811. /**
  812. * Success ajax response for Recommission/Decommission slaves
  813. * @param data
  814. * @param ajaxOptions
  815. */
  816. decommissionSuccessCallback: function(data, ajaxOptions) {
  817. if(data && (data.Requests || data.resources[0].RequestSchedule) ) {
  818. if (!App.testMode) {
  819. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  820. }
  821. // load data (if we need to show this background operations popup) from persist
  822. App.router.get('applicationController').dataLoading().done(function (initValue) {
  823. if (initValue) {
  824. App.router.get('backgroundOperationsController').showPopup();
  825. }
  826. });
  827. }
  828. else {
  829. console.log('cannot get request id from ', data);
  830. }
  831. },
  832. doRecommissionAndStart: function(hostNames, serviceName, componentName, slaveType){
  833. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  834. var context_1 = Em.I18n.t(contextNameString_1);
  835. var contextNameString_2 = 'requestInfo.startHostComponent.' + slaveType.toLowerCase();
  836. var startContext = Em.I18n.t(contextNameString_2);
  837. App.ajax.send({
  838. name: 'host.host_component.recommission_and_restart',
  839. sender: this,
  840. data: {
  841. intervalTimeSeconds: 1,
  842. tolerateSize : 1,
  843. batches:[
  844. {
  845. "order_id" : 1,
  846. "type" : "POST",
  847. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  848. "RequestBodyInfo" : {
  849. "RequestInfo" : {
  850. "context" : context_1,
  851. "command" : "DECOMMISSION",
  852. "parameters" : {
  853. "slave_type": slaveType,
  854. "included_hosts": hostNames
  855. }
  856. },
  857. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  858. }
  859. },
  860. {
  861. "order_id": 2,
  862. "type": "PUT",
  863. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  864. "RequestBodyInfo" : {
  865. "RequestInfo" : {
  866. context: startContext,
  867. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  868. },
  869. "Body": {
  870. HostRoles: {
  871. state: "STARTED"
  872. }
  873. }
  874. }
  875. }
  876. ]
  877. },
  878. success: 'decommissionSuccessCallback',
  879. error: 'decommissionErrorCallback'
  880. });
  881. },
  882. doRecommissionAndRestart: function(hostNames, serviceName, componentName, slaveType){
  883. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  884. var context_1 = Em.I18n.t(contextNameString_1);
  885. var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
  886. var context_2 = Em.I18n.t(contextNameString_2);
  887. App.ajax.send({
  888. name: 'host.host_component.recommission_and_restart',
  889. sender: this,
  890. data: {
  891. intervalTimeSeconds: 1,
  892. tolerateSize : 1,
  893. batches:[
  894. {
  895. "order_id" : 1,
  896. "type" : "POST",
  897. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  898. "RequestBodyInfo" : {
  899. "RequestInfo" : {
  900. "context" : context_1,
  901. "command" : "DECOMMISSION",
  902. "parameters" : {
  903. "slave_type": slaveType,
  904. "included_hosts": hostNames
  905. }
  906. },
  907. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  908. }
  909. },
  910. {
  911. "order_id" : 2,
  912. "type" : "POST",
  913. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  914. "RequestBodyInfo" : {
  915. "RequestInfo" : {
  916. "context" : context_2,
  917. "command" : "RESTART",
  918. "service_name" : serviceName,
  919. "component_name" : slaveType,
  920. "hosts" : hostNames
  921. }
  922. }
  923. }
  924. ]
  925. },
  926. success: 'decommissionSuccessCallback',
  927. error: 'decommissionErrorCallback'
  928. });
  929. },
  930. doAction: function(option) {
  931. switch (option.context.action) {
  932. case "deleteHost":
  933. this.validateAndDeleteHost();
  934. break;
  935. case "startAllComponents":
  936. if (!this.get('content.isNotHeartBeating')) this.doStartAllComponents();
  937. break;
  938. case "stopAllComponents":
  939. if (!this.get('content.isNotHeartBeating')) this.doStopAllComponents();
  940. break;
  941. case "restartAllComponents":
  942. if (!this.get('content.isNotHeartBeating')) this.doRestartAllComponents();
  943. break;
  944. case "onOffPassiveModeForHost":
  945. this.onOffPassiveModeForHost(option.context);
  946. break;
  947. default:
  948. break;
  949. }
  950. },
  951. onOffPassiveModeForHost: function(context) {
  952. var state = context.active ? 'ON' : 'OFF';
  953. var self = this;
  954. var message = context.label + ' for host';
  955. App.showConfirmationPopup(function() {
  956. self.hostPassiveModeRequest(state, message)
  957. },
  958. Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off',this.get('content.hostName'))
  959. );
  960. },
  961. hostPassiveModeRequest: function(state,message) {
  962. App.ajax.send({
  963. name: 'bulk_request.hosts.passive_state',
  964. sender: this,
  965. data: {
  966. hostNames: this.get('content.hostName'),
  967. passive_state: state,
  968. requestInfo: message
  969. },
  970. success: 'updateHost'
  971. });
  972. },
  973. updateHost: function(data, opt, params) {
  974. this.set('content.passiveState', params.passive_state);
  975. App.router.get('clusterController').loadUpdatedStatus(function(){
  976. batchUtils.infoPassiveState(params.passive_state);
  977. });
  978. },
  979. doStartAllComponents: function() {
  980. var self = this;
  981. var components = this.get('serviceNonClientActiveComponents');
  982. var componentsLength = components == null ? 0 : components.get('length');
  983. if (componentsLength > 0) {
  984. App.showConfirmationPopup(function() {
  985. self.sendStartComponentCommand(components, Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  986. });
  987. }
  988. },
  989. doStopAllComponents: function() {
  990. var self = this;
  991. var components = this.get('serviceNonClientActiveComponents');
  992. var componentsLength = components == null ? 0 : components.get('length');
  993. if (componentsLength > 0) {
  994. App.showConfirmationPopup(function() {
  995. self.sendStopComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  996. });
  997. }
  998. },
  999. doRestartAllComponents: function() {
  1000. var self = this;
  1001. var components = this.get('serviceActiveComponents');
  1002. var componentsLength = components == null ? 0 : components.get('length');
  1003. if (componentsLength > 0) {
  1004. App.showConfirmationPopup(function() {
  1005. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')));
  1006. });
  1007. }
  1008. },
  1009. /**
  1010. * Deletion of hosts not supported for this version
  1011. */
  1012. validateAndDeleteHost: function () {
  1013. if (!App.supports.deleteHost) {
  1014. return;
  1015. }
  1016. var stoppedStates = [App.HostComponentStatus.stopped,
  1017. App.HostComponentStatus.install_failed,
  1018. App.HostComponentStatus.upgrade_failed,
  1019. App.HostComponentStatus.init,
  1020. App.HostComponentStatus.unknown];
  1021. var masterComponents = [];
  1022. var runningComponents = [];
  1023. var unknownComponents = [];
  1024. var nonDeletableComponents = [];
  1025. var lastComponents = [];
  1026. var componentsOnHost = this.get('content.hostComponents');
  1027. var allComponents = App.HostComponent.find();
  1028. var zkServerInstalled = false;
  1029. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  1030. componentsOnHost.forEach(function (cInstance) {
  1031. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  1032. zkServerInstalled = true;
  1033. }
  1034. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  1035. lastComponents.push(cInstance.get('displayName'));
  1036. }
  1037. var workStatus = cInstance.get('workStatus');
  1038. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  1039. masterComponents.push(cInstance.get('displayName'));
  1040. }
  1041. if (stoppedStates.indexOf(workStatus) < 0) {
  1042. runningComponents.push(cInstance.get('displayName'));
  1043. }
  1044. if (!cInstance.get('isDeletable')) {
  1045. nonDeletableComponents.push(cInstance.get('displayName'));
  1046. }
  1047. if (workStatus === App.HostComponentStatus.unknown) {
  1048. unknownComponents.push(cInstance.get('displayName'));
  1049. }
  1050. });
  1051. }
  1052. if (masterComponents.length > 0) {
  1053. this.raiseDeleteComponentsError(masterComponents, 'masterList');
  1054. return;
  1055. } else if (nonDeletableComponents.length > 0) {
  1056. this.raiseDeleteComponentsError(nonDeletableComponents, 'nonDeletableList');
  1057. return;
  1058. } else if (runningComponents.length > 0) {
  1059. this.raiseDeleteComponentsError(runningComponents, 'runningList');
  1060. return;
  1061. }
  1062. if (zkServerInstalled) {
  1063. var self = this;
  1064. App.showConfirmationPopup(function() {
  1065. self._doDeleteHost(unknownComponents, lastComponents);
  1066. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1067. }
  1068. else {
  1069. this._doDeleteHost(unknownComponents, lastComponents);
  1070. }
  1071. },
  1072. raiseDeleteComponentsError: function (components, type) {
  1073. App.ModalPopup.show({
  1074. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1075. type: type,
  1076. showBodyEnd: function() {
  1077. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1078. }.property(),
  1079. components: components,
  1080. componentsStr: function() {
  1081. return this.get('components').join(", ");
  1082. }.property(),
  1083. componentsBody: function() {
  1084. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body').format(this.get('components').length);
  1085. }.property(),
  1086. componentsBodyEnd: function() {
  1087. if (this.get('showBodyEnd')) {
  1088. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body.end');
  1089. }
  1090. return '';
  1091. }.property(),
  1092. bodyClass: Em.View.extend({
  1093. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1094. }),
  1095. secondary: null
  1096. })
  1097. },
  1098. /**
  1099. * show confirmation popup to delete host
  1100. */
  1101. _doDeleteHost: function(unknownComponents,lastComponents) {
  1102. var self = this;
  1103. App.ModalPopup.show({
  1104. header: Em.I18n.t('hosts.delete.popup.title'),
  1105. deletePopupBody: function() {
  1106. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1107. }.property(),
  1108. lastComponent: function() {
  1109. if (lastComponents && lastComponents.length) {
  1110. this.set('isChecked', false);
  1111. return true;
  1112. } else {
  1113. this.set('isChecked', true);
  1114. return false;
  1115. }
  1116. }.property(),
  1117. disablePrimary: function () {
  1118. return !this.get('isChecked');
  1119. }.property('isChecked'),
  1120. isChecked: false,
  1121. lastComponentError: Em.View.extend({
  1122. template: Ember.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  1123. }),
  1124. unknownComponents: function() {
  1125. if (unknownComponents && unknownComponents.length) {
  1126. return unknownComponents.join(", ");
  1127. }
  1128. return '';
  1129. }.property(),
  1130. bodyClass: Em.View.extend({
  1131. templateName: require('templates/main/host/details/doDeleteHostPopup')
  1132. }),
  1133. onPrimary: function() {
  1134. self.set('fromDeleteHost', true);
  1135. var allComponents = self.get('content.hostComponents');
  1136. var deleteError = null;
  1137. allComponents.forEach(function(component){
  1138. if (!deleteError) {
  1139. deleteError = self._doDeleteHostComponent(component);
  1140. }
  1141. });
  1142. if (!deleteError) {
  1143. App.ajax.send({
  1144. name: 'host.delete',
  1145. sender: this,
  1146. data: {
  1147. hostName: self.get('content.hostName')
  1148. },
  1149. success: 'deleteHostSuccessCallback',
  1150. error: 'deleteHostErrorCallback'
  1151. });
  1152. }
  1153. else {
  1154. this.hide();
  1155. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  1156. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  1157. }
  1158. },
  1159. deleteHostSuccessCallback: function(data) {
  1160. var dialogSelf = this;
  1161. App.router.get('updateController').updateHost(function(){
  1162. self.loadConfigs();
  1163. dialogSelf.hide();
  1164. App.router.transitionTo('hosts.index');
  1165. });
  1166. },
  1167. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  1168. console.log('Error deleting host.');
  1169. console.log(textStatus);
  1170. console.log(errorThrown);
  1171. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  1172. self.loadConfigs();
  1173. this.hide();
  1174. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  1175. }
  1176. })
  1177. },
  1178. restartAllStaleConfigComponents: function() {
  1179. var self = this;
  1180. App.showConfirmationPopup(function () {
  1181. var staleComponents = self.get('content.componentsWithStaleConfigs');
  1182. batchUtils.restartHostComponents(staleComponents, Em.I18n.t('rollingrestart.context.allWithStaleConfigsOnSelectedHost').format(self.get('content.hostName')));
  1183. });
  1184. },
  1185. /**
  1186. * open Reassign Master Wizard with selected component
  1187. * @param event
  1188. */
  1189. moveComponent: function (event) {
  1190. App.showConfirmationPopup(function() {
  1191. var component = event.context;
  1192. var reassignMasterController = App.router.get('reassignMasterController');
  1193. reassignMasterController.saveComponentToReassign(component);
  1194. reassignMasterController.getSecurityStatus();
  1195. reassignMasterController.setCurrentStep('1');
  1196. App.router.transitionTo('reassign');
  1197. });
  1198. },
  1199. /**
  1200. * Restart clients host components to apply config changes
  1201. */
  1202. refreshConfigs: function(event) {
  1203. var self = this;
  1204. var components = event.context.filter(function(component) {
  1205. return component.get('staleConfigs');
  1206. });
  1207. if (components.get('length') > 0) {
  1208. App.showConfirmationPopup(function() {
  1209. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allClientsOnSelectedHost').format(self.get('content.hostName')));
  1210. });
  1211. }
  1212. }
  1213. });