details.js 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  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'), self.get('content.hostName')));
  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.doDecommissionRegionServer(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. * Performs Decommission (for RegionServer)
  714. */
  715. doDecommissionRegionServer: function(hostNames, serviceName, componentName, slaveType){
  716. App.ajax.send({
  717. name: 'host.host_component.recommission_and_restart',
  718. sender: this,
  719. data: {
  720. intervalTimeSeconds: 1,
  721. tolerateSize : 0,
  722. batches:[
  723. {
  724. "order_id" : 1,
  725. "type" : "POST",
  726. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  727. "RequestBodyInfo" : {
  728. "RequestInfo" : {
  729. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  730. "command" : "DECOMMISSION",
  731. "parameters" : {
  732. "slave_type": slaveType,
  733. "excluded_hosts": hostNames
  734. }
  735. },
  736. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  737. }
  738. },
  739. {
  740. "order_id": 2,
  741. "type": "PUT",
  742. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  743. "RequestBodyInfo" : {
  744. "RequestInfo" : {
  745. context: Em.I18n.t('hosts.host.regionserver.decommission.batch2'),
  746. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  747. },
  748. "Body": {
  749. HostRoles: {
  750. state: "INSTALLED"
  751. }
  752. }
  753. }
  754. },
  755. {
  756. "order_id" : 3,
  757. "type" : "POST",
  758. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  759. "RequestBodyInfo" : {
  760. "RequestInfo" : {
  761. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  762. "command" : "DECOMMISSION",
  763. "service_name" : serviceName,
  764. "component_name" : componentName,
  765. "parameters" : {
  766. "slave_type": slaveType,
  767. "excluded_hosts": hostNames,
  768. "mark_draining_only": "true"
  769. }
  770. }
  771. }
  772. }
  773. ]
  774. },
  775. success: 'decommissionSuccessCallback',
  776. error: 'decommissionErrorCallback'
  777. });
  778. },
  779. decommissionErrorCallback: function (request, ajaxOptions, error) {
  780. console.log('ERROR: '+ error);
  781. },
  782. /**
  783. * Success ajax response for Recommission/Decommission slaves
  784. * @param data
  785. * @param ajaxOptions
  786. */
  787. decommissionSuccessCallback: function(data, ajaxOptions) {
  788. if(data && (data.Requests || data.resources[0].RequestSchedule) ) {
  789. if (!App.testMode) {
  790. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  791. }
  792. // load data (if we need to show this background operations popup) from persist
  793. App.router.get('applicationController').dataLoading().done(function (initValue) {
  794. if (initValue) {
  795. App.router.get('backgroundOperationsController').showPopup();
  796. }
  797. });
  798. }
  799. else {
  800. console.log('cannot get request id from ', data);
  801. }
  802. },
  803. doRecommissionAndStart: function(hostNames, serviceName, componentName, slaveType){
  804. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  805. var context_1 = Em.I18n.t(contextNameString_1);
  806. var contextNameString_2 = 'requestInfo.startHostComponent.' + slaveType.toLowerCase();
  807. var startContext = Em.I18n.t(contextNameString_2);
  808. App.ajax.send({
  809. name: 'host.host_component.recommission_and_restart',
  810. sender: this,
  811. data: {
  812. intervalTimeSeconds: 1,
  813. tolerateSize : 1,
  814. batches:[
  815. {
  816. "order_id" : 1,
  817. "type" : "POST",
  818. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  819. "RequestBodyInfo" : {
  820. "RequestInfo" : {
  821. "context" : context_1,
  822. "command" : "DECOMMISSION",
  823. "parameters" : {
  824. "slave_type": slaveType,
  825. "included_hosts": hostNames
  826. }
  827. },
  828. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  829. }
  830. },
  831. {
  832. "order_id": 2,
  833. "type": "PUT",
  834. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  835. "RequestBodyInfo" : {
  836. "RequestInfo" : {
  837. context: startContext,
  838. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  839. },
  840. "Body": {
  841. HostRoles: {
  842. state: "STARTED"
  843. }
  844. }
  845. }
  846. }
  847. ]
  848. },
  849. success: 'decommissionSuccessCallback',
  850. error: 'decommissionErrorCallback'
  851. });
  852. },
  853. doRecommissionAndRestart: function(hostNames, serviceName, componentName, slaveType){
  854. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  855. var context_1 = Em.I18n.t(contextNameString_1);
  856. var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
  857. var context_2 = Em.I18n.t(contextNameString_2);
  858. App.ajax.send({
  859. name: 'host.host_component.recommission_and_restart',
  860. sender: this,
  861. data: {
  862. intervalTimeSeconds: 1,
  863. tolerateSize : 1,
  864. batches:[
  865. {
  866. "order_id" : 1,
  867. "type" : "POST",
  868. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  869. "RequestBodyInfo" : {
  870. "RequestInfo" : {
  871. "context" : context_1,
  872. "command" : "DECOMMISSION",
  873. "parameters" : {
  874. "slave_type": slaveType,
  875. "included_hosts": hostNames
  876. }
  877. },
  878. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  879. }
  880. },
  881. {
  882. "order_id" : 2,
  883. "type" : "POST",
  884. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  885. "RequestBodyInfo" : {
  886. "RequestInfo" : {
  887. "context" : context_2,
  888. "command" : "RESTART",
  889. "service_name" : serviceName,
  890. "component_name" : slaveType,
  891. "hosts" : hostNames
  892. }
  893. }
  894. }
  895. ]
  896. },
  897. success: 'decommissionSuccessCallback',
  898. error: 'decommissionErrorCallback'
  899. });
  900. },
  901. doAction: function(option) {
  902. switch (option.context.action) {
  903. case "deleteHost":
  904. this.validateAndDeleteHost();
  905. break;
  906. case "startAllComponents":
  907. if (!this.get('content.isNotHeartBeating')) this.doStartAllComponents();
  908. break;
  909. case "stopAllComponents":
  910. if (!this.get('content.isNotHeartBeating')) this.doStopAllComponents();
  911. break;
  912. case "restartAllComponents":
  913. if (!this.get('content.isNotHeartBeating')) this.doRestartAllComponents();
  914. break;
  915. case "onOffPassiveModeForHost":
  916. this.onOffPassiveModeForHost(option.context);
  917. break;
  918. default:
  919. break;
  920. }
  921. },
  922. onOffPassiveModeForHost: function(context) {
  923. var state = context.active ? 'ON' : 'OFF';
  924. var self = this;
  925. var message = context.label + ' for host';
  926. App.showConfirmationPopup(function() {
  927. self.hostPassiveModeRequest(state, message)
  928. },
  929. Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off',this.get('content.hostName'))
  930. );
  931. },
  932. hostPassiveModeRequest: function(state,message) {
  933. App.ajax.send({
  934. name: 'bulk_request.hosts.passive_state',
  935. sender: this,
  936. data: {
  937. hostNames: this.get('content.hostName'),
  938. passive_state: state,
  939. requestInfo: message
  940. },
  941. success: 'updateHost'
  942. });
  943. },
  944. updateHost: function(data, opt, params) {
  945. this.set('content.passiveState', params.passive_state);
  946. App.router.get('clusterController').loadUpdatedStatus(function(){
  947. batchUtils.infoPassiveState(params.passive_state);
  948. });
  949. },
  950. doStartAllComponents: function() {
  951. var self = this;
  952. var components = this.get('serviceNonClientActiveComponents');
  953. var componentsLength = components == null ? 0 : components.get('length');
  954. if (componentsLength > 0) {
  955. App.showConfirmationPopup(function() {
  956. self.sendStartComponentCommand(components, Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  957. });
  958. }
  959. },
  960. doStopAllComponents: function() {
  961. var self = this;
  962. var components = this.get('serviceNonClientActiveComponents');
  963. var componentsLength = components == null ? 0 : components.get('length');
  964. if (componentsLength > 0) {
  965. App.showConfirmationPopup(function() {
  966. self.sendStopComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  967. });
  968. }
  969. },
  970. doRestartAllComponents: function() {
  971. var self = this;
  972. var components = this.get('serviceActiveComponents');
  973. var componentsLength = components == null ? 0 : components.get('length');
  974. if (componentsLength > 0) {
  975. App.showConfirmationPopup(function() {
  976. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')));
  977. });
  978. }
  979. },
  980. /**
  981. * Deletion of hosts not supported for this version
  982. */
  983. validateAndDeleteHost: function () {
  984. if (!App.supports.deleteHost) {
  985. return;
  986. }
  987. var stoppedStates = [App.HostComponentStatus.stopped,
  988. App.HostComponentStatus.install_failed,
  989. App.HostComponentStatus.upgrade_failed,
  990. App.HostComponentStatus.init,
  991. App.HostComponentStatus.unknown];
  992. var masterComponents = [];
  993. var runningComponents = [];
  994. var unknownComponents = [];
  995. var nonDeletableComponents = [];
  996. var lastComponents = [];
  997. var componentsOnHost = this.get('content.hostComponents');
  998. var allComponents = App.HostComponent.find();
  999. var zkServerInstalled = false;
  1000. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  1001. componentsOnHost.forEach(function (cInstance) {
  1002. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  1003. zkServerInstalled = true;
  1004. }
  1005. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  1006. lastComponents.push(cInstance.get('displayName'));
  1007. }
  1008. var workStatus = cInstance.get('workStatus');
  1009. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  1010. masterComponents.push(cInstance.get('displayName'));
  1011. }
  1012. if (stoppedStates.indexOf(workStatus) < 0) {
  1013. runningComponents.push(cInstance.get('displayName'));
  1014. }
  1015. if (!cInstance.get('isDeletable')) {
  1016. nonDeletableComponents.push(cInstance.get('displayName'));
  1017. }
  1018. if (workStatus === App.HostComponentStatus.unknown) {
  1019. unknownComponents.push(cInstance.get('displayName'));
  1020. }
  1021. });
  1022. }
  1023. if (masterComponents.length > 0) {
  1024. this.raiseDeleteComponentsError(masterComponents, 'masterList');
  1025. return;
  1026. } else if (nonDeletableComponents.length > 0) {
  1027. this.raiseDeleteComponentsError(nonDeletableComponents, 'nonDeletableList');
  1028. return;
  1029. } else if (runningComponents.length > 0) {
  1030. this.raiseDeleteComponentsError(runningComponents, 'runningList');
  1031. return;
  1032. }
  1033. if (zkServerInstalled) {
  1034. var self = this;
  1035. App.showConfirmationPopup(function() {
  1036. self._doDeleteHost(unknownComponents, lastComponents);
  1037. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1038. }
  1039. else {
  1040. this._doDeleteHost(unknownComponents, lastComponents);
  1041. }
  1042. },
  1043. raiseDeleteComponentsError: function (components, type) {
  1044. App.ModalPopup.show({
  1045. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1046. type: type,
  1047. showBodyEnd: function() {
  1048. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1049. }.property(),
  1050. components: components,
  1051. componentsStr: function() {
  1052. return this.get('components').join(", ");
  1053. }.property(),
  1054. componentsBody: function() {
  1055. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body').format(this.get('components').length);
  1056. }.property(),
  1057. componentsBodyEnd: function() {
  1058. if (this.get('showBodyEnd')) {
  1059. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body.end');
  1060. }
  1061. return '';
  1062. }.property(),
  1063. bodyClass: Em.View.extend({
  1064. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1065. }),
  1066. secondary: null
  1067. })
  1068. },
  1069. /**
  1070. * show confirmation popup to delete host
  1071. */
  1072. _doDeleteHost: function(unknownComponents,lastComponents) {
  1073. var self = this;
  1074. App.ModalPopup.show({
  1075. header: Em.I18n.t('hosts.delete.popup.title'),
  1076. deletePopupBody: function() {
  1077. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1078. }.property(),
  1079. lastComponent: function() {
  1080. if (lastComponents && lastComponents.length) {
  1081. this.set('isChecked', false);
  1082. return true;
  1083. } else {
  1084. this.set('isChecked', true);
  1085. return false;
  1086. }
  1087. }.property(),
  1088. disablePrimary: function () {
  1089. return !this.get('isChecked');
  1090. }.property('isChecked'),
  1091. isChecked: false,
  1092. lastComponentError: Em.View.extend({
  1093. template: Ember.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  1094. }),
  1095. unknownComponents: function() {
  1096. if (unknownComponents && unknownComponents.length) {
  1097. return unknownComponents.join(", ");
  1098. }
  1099. return '';
  1100. }.property(),
  1101. bodyClass: Em.View.extend({
  1102. templateName: require('templates/main/host/details/doDeleteHostPopup')
  1103. }),
  1104. onPrimary: function() {
  1105. self.set('fromDeleteHost', true);
  1106. var allComponents = self.get('content.hostComponents');
  1107. var deleteError = null;
  1108. allComponents.forEach(function(component){
  1109. if (!deleteError) {
  1110. deleteError = self._doDeleteHostComponent(component);
  1111. }
  1112. });
  1113. if (!deleteError) {
  1114. App.ajax.send({
  1115. name: 'host.delete',
  1116. sender: this,
  1117. data: {
  1118. hostName: self.get('content.hostName')
  1119. },
  1120. success: 'deleteHostSuccessCallback',
  1121. error: 'deleteHostErrorCallback'
  1122. });
  1123. }
  1124. else {
  1125. this.hide();
  1126. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  1127. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  1128. }
  1129. },
  1130. deleteHostSuccessCallback: function(data) {
  1131. var dialogSelf = this;
  1132. App.router.get('updateController').updateHost(function(){
  1133. self.loadConfigs();
  1134. dialogSelf.hide();
  1135. App.router.transitionTo('hosts.index');
  1136. });
  1137. },
  1138. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  1139. console.log('Error deleting host.');
  1140. console.log(textStatus);
  1141. console.log(errorThrown);
  1142. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  1143. self.loadConfigs();
  1144. this.hide();
  1145. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  1146. }
  1147. })
  1148. },
  1149. restartAllStaleConfigComponents: function() {
  1150. var self = this;
  1151. App.showConfirmationPopup(function () {
  1152. var staleComponents = self.get('content.componentsWithStaleConfigs');
  1153. batchUtils.restartHostComponents(staleComponents, Em.I18n.t('rollingrestart.context.allWithStaleConfigsOnSelectedHost').format(self.get('content.hostName')));
  1154. });
  1155. },
  1156. /**
  1157. * open Reassign Master Wizard with selected component
  1158. * @param event
  1159. */
  1160. moveComponent: function (event) {
  1161. App.showConfirmationPopup(function() {
  1162. var component = event.context;
  1163. var reassignMasterController = App.router.get('reassignMasterController');
  1164. reassignMasterController.saveComponentToReassign(component);
  1165. reassignMasterController.getSecurityStatus();
  1166. reassignMasterController.setCurrentStep('1');
  1167. App.router.transitionTo('reassign');
  1168. });
  1169. },
  1170. /**
  1171. * Restart clients host components to apply config changes
  1172. */
  1173. refreshConfigs: function(event) {
  1174. var self = this;
  1175. var components = event.context.filter(function(component) {
  1176. return component.get('staleConfigs');
  1177. });
  1178. if (components.get('length') > 0) {
  1179. App.showConfirmationPopup(function() {
  1180. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allClientsOnSelectedHost').format(self.get('content.hostName')));
  1181. });
  1182. }
  1183. }
  1184. });