details.js 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886
  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. var componentsUtils = require('utils/components');
  21. var stringUtils = require('utils/string_utils');
  22. App.MainHostDetailsController = Em.Controller.extend({
  23. name: 'mainHostDetailsController',
  24. /**
  25. * Viewed host
  26. * @type {App.Host|null}
  27. */
  28. content: null,
  29. /**
  30. * Does user come from hosts page
  31. * @type {bool}
  32. */
  33. isFromHosts: false,
  34. /**
  35. * path to page visited before
  36. * @type {string}
  37. */
  38. referer: '',
  39. /**
  40. * Open dashboard page
  41. * @method routeHome
  42. */
  43. routeHome: function () {
  44. App.router.transitionTo('main.dashboard.index');
  45. },
  46. /**
  47. * List of active (not in passive state) host components
  48. * @type {Ember.Enumerable}
  49. */
  50. serviceActiveComponents: function () {
  51. return this.get('content.hostComponents').filterProperty('service.isInPassive', false);
  52. }.property('content.hostComponents'),
  53. /**
  54. * List of active host components which aren't clients
  55. * @type {Ember.Enumerable}
  56. */
  57. serviceNonClientActiveComponents: function () {
  58. return this.get('serviceActiveComponents').filterProperty('isClient', false);
  59. }.property('serviceActiveComponents'),
  60. /**
  61. * send command to server to start selected host component
  62. * @param {object} event
  63. * @method startComponent
  64. */
  65. startComponent: function (event) {
  66. var self = this;
  67. return App.showConfirmationPopup(function () {
  68. var component = event.context;
  69. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  70. self.sendComponentCommand(component, context, App.HostComponentStatus.started);
  71. });
  72. },
  73. /**
  74. * send command to server to stop selected host component
  75. * @param {object} event
  76. * @method startComponent
  77. */
  78. stopComponent: function (event) {
  79. var self = this;
  80. return App.showConfirmationPopup(function () {
  81. var component = event.context;
  82. var context = Em.I18n.t('requestInfo.stopHostComponent') + " " + component.get('displayName');
  83. self.sendComponentCommand(component, context, App.HostComponentStatus.stopped);
  84. });
  85. },
  86. /**
  87. * PUTs a command to server to start/stop a component. If no
  88. * specific component is provided, all components are started.
  89. * @param {object} component When <code>null</code> all startable components are started.
  90. * @param {String} context Context under which this command is beign sent.
  91. * @param {String} state - desired state of component can be 'STARTED' or 'STOPPED'
  92. * @method sendComponentCommand
  93. */
  94. sendComponentCommand: function (component, context, state) {
  95. var data = {
  96. hostName: this.get('content.hostName'),
  97. context: context,
  98. component: component,
  99. HostRoles: {
  100. state: state
  101. }
  102. };
  103. if (Array.isArray(component)) {
  104. data.query = "HostRoles/component_name.in(" + component.mapProperty('componentName').join(',') + ")";
  105. } else {
  106. data.componentName = component.get('componentName');
  107. data.serviceName = component.get('service.serviceName');
  108. }
  109. App.ajax.send({
  110. name: (Array.isArray(component)) ? 'common.host.host_components.update' : 'common.host.host_component.update',
  111. sender: this,
  112. data: data,
  113. success: 'sendComponentCommandSuccessCallback',
  114. error: 'ajaxErrorCallback'
  115. });
  116. },
  117. /**
  118. * Success callback for stop/start host component request
  119. * @param {object} data
  120. * @param {object} opt
  121. * @param {object} params
  122. * @method stopComponentSuccessCallback
  123. */
  124. sendComponentCommandSuccessCallback: function (data, opt, params) {
  125. var running = (params.HostRoles.state === App.HostComponentStatus.stopped) ? App.HostComponentStatus.stopping : App.HostComponentStatus.starting;
  126. console.log('Send request for ' + running + ' successfully');
  127. params.component.set('workStatus', running);
  128. if (App.get('testMode')) {
  129. this.mimicWorkStatusChange(params.component, running, params.HostRoles.state);
  130. }
  131. this.showBackgroundOperationsPopup();
  132. },
  133. /**
  134. * Default error-callback for ajax-requests in current page
  135. * @param {object} request
  136. * @param {object} ajaxOptions
  137. * @param {string} error
  138. * @param {object} opt
  139. * @param {object} params
  140. * @method ajaxErrorCallback
  141. */
  142. ajaxErrorCallback: function (request, ajaxOptions, error, opt, params) {
  143. return componentsUtils.ajaxErrorCallback(request, ajaxOptions, error, opt, params);
  144. },
  145. /**
  146. * mimic status transition in test mode
  147. * @param entity
  148. * @param transitionalState
  149. * @param finalState
  150. */
  151. mimicWorkStatusChange: function (entity, transitionalState, finalState) {
  152. if (Em.isArray(entity)) {
  153. entity.forEach(function (item) {
  154. item.set('workStatus', transitionalState);
  155. setTimeout(function () {
  156. item.set('workStatus', finalState);
  157. }, App.testModeDelayForActions);
  158. });
  159. } else {
  160. entity.set('workStatus', transitionalState);
  161. setTimeout(function () {
  162. entity.set('workStatus', finalState);
  163. }, App.testModeDelayForActions);
  164. }
  165. },
  166. /**
  167. * load data (if we need to show this background operations popup) from persist
  168. * @param callback
  169. */
  170. showBackgroundOperationsPopup: function (callback) {
  171. App.router.get('applicationController').dataLoading().done(function (initValue) {
  172. if (initValue) {
  173. App.router.get('backgroundOperationsController').showPopup();
  174. }
  175. if (typeof callback === 'function') {
  176. callback();
  177. }
  178. });
  179. },
  180. /**
  181. * Send command to server to delete selected host component
  182. * @param {object} event
  183. * @method deleteComponent
  184. */
  185. deleteComponent: function (event) {
  186. var self = this;
  187. var component = event.context;
  188. var componentName = component.get('componentName');
  189. var displayName = component.get('displayName');
  190. var isLastComponent = (this.getTotalComponent(component) === 1);
  191. return App.ModalPopup.show({
  192. header: Em.I18n.t('popup.confirmation.commonHeader'),
  193. primary: Em.I18n.t('hosts.host.deleteComponent.popup.confirm'),
  194. bodyClass: Em.View.extend({
  195. templateName: require('templates/main/host/details/deleteComponentPopup')
  196. }),
  197. isHiveMetastore: function () {
  198. return componentName == 'HIVE_METASTORE';
  199. }.property(),
  200. deleteHiveMetastoreMsg: Em.View.extend({
  201. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteHiveMetastore'))
  202. }),
  203. isChecked: false,
  204. disablePrimary: function () {
  205. return !this.get('isChecked');
  206. }.property('isChecked'),
  207. lastComponent: function () {
  208. this.set('isChecked', !isLastComponent);
  209. return isLastComponent;
  210. }.property(),
  211. isZkServer: function () {
  212. return componentName == 'ZOOKEEPER_SERVER';
  213. }.property(),
  214. lastComponentError: Em.View.extend({
  215. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  216. }),
  217. restartNagiosMsg: Em.View.extend({
  218. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.msg2').format(displayName))
  219. }),
  220. deleteComponentMsg: function () {
  221. return Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(displayName);
  222. }.property(),
  223. deleteZkServerMsg: Em.View.extend({
  224. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteZooKeeperServer'))
  225. }),
  226. onPrimary: function () {
  227. var popup = this;
  228. self._doDeleteHostComponent(component, function () {
  229. self.set('redrawComponents', true);
  230. popup.hide();
  231. });
  232. }
  233. });
  234. },
  235. /**
  236. * get total count of host-components
  237. * @method getTotalComponent
  238. * @param component
  239. * @return {Number}
  240. */
  241. getTotalComponent: function (component) {
  242. var count;
  243. if (component.get('isSlave')) {
  244. count = App.SlaveComponent.find(component.get('componentName')).get('totalCount');
  245. } else if (component.get('isClient')) {
  246. count = App.ClientComponent.find(component.get('componentName')).get('totalCount');
  247. } else {
  248. count = App.HostComponent.find().filterProperty('componentName', component.get('componentName')).get('length');
  249. }
  250. return count || 0;
  251. },
  252. /**
  253. * Trigger to reset list of master/slaves components on the view
  254. * @type {bool}
  255. */
  256. redrawComponents: false,
  257. /**
  258. * Deletes the given host component, or all host components.
  259. *
  260. * @param {object|null} component When <code>null</code> all host components are deleted.
  261. * @return <code>null</code> when components get deleted.
  262. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  263. * when components failed to get deleted.
  264. * @method _doDeleteHostComponent
  265. */
  266. _doDeleteHostComponent: function (component, callback) {
  267. callback = callback || Em.K;
  268. App.ajax.send({
  269. name: (Em.isNone(component)) ? 'common.delete.host' : 'common.delete.host_component',
  270. sender: this,
  271. data: {
  272. componentName: (component) ? component.get('componentName') : '',
  273. hostName: this.get('content.hostName')
  274. },
  275. success: '_doDeleteHostComponentSuccessCallback',
  276. error: '_doDeleteHostComponentErrorCallback'
  277. }).then(callback, callback);
  278. },
  279. /**
  280. * Result of delete component(s) request
  281. * @type {object}
  282. */
  283. _deletedHostComponentResult: null,
  284. /**
  285. * Success callback for delete host component request
  286. * @method _doDeleteHostComponentSuccessCallback
  287. */
  288. _doDeleteHostComponentSuccessCallback: function (response, request, data) {
  289. this.set('_deletedHostComponentResult', null);
  290. this.removeHostComponentModel(data.componentName, data.hostName);
  291. if (data.componentName == 'ZOOKEEPER_SERVER') {
  292. this.set('fromDeleteZkServer', true);
  293. this.loadConfigs();
  294. } else if (data.componentName == 'HIVE_METASTORE') {
  295. this.set('deleteHiveMetaStore', true);
  296. this.loadConfigs('loadHiveConfigs');
  297. }
  298. },
  299. /**
  300. * Error-callback for delete host component request
  301. * @param {object} xhr
  302. * @param {string} textStatus
  303. * @param {object} errorThrown
  304. * @method _doDeleteHostComponentErrorCallback
  305. */
  306. _doDeleteHostComponentErrorCallback: function (xhr, textStatus, errorThrown, data) {
  307. console.log('Error deleting host component');
  308. console.log(textStatus);
  309. console.log(errorThrown);
  310. this.set('_deletedHostComponentResult', {xhr: xhr, url: data.url, method: 'DELETE'});
  311. },
  312. /**
  313. * Remove host component data from App.HostComponent model.
  314. *
  315. * @param {String} componentName
  316. * @param {String} hostName
  317. */
  318. removeHostComponentModel: function(componentName, hostName) {
  319. var component = App.HostComponent.find().filterProperty('componentName', componentName).findProperty('hostName', hostName);
  320. App.serviceMapper.deleteRecord(component);
  321. },
  322. /**
  323. * Send command to server to upgrade selected host component
  324. * @param {object} event
  325. * @method upgradeComponent
  326. */
  327. upgradeComponent: function (event) {
  328. var self = this;
  329. var component = event.context;
  330. return App.showConfirmationPopup(function () {
  331. App.ajax.send({
  332. name: 'host.host_component.upgrade',
  333. sender: self,
  334. data: {
  335. component: component,
  336. hostName: self.get('content.hostName'),
  337. componentName: component.get('componentName'),
  338. data: JSON.stringify({
  339. RequestInfo: {
  340. "context": Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  341. },
  342. Body: {
  343. HostRoles: {
  344. stack_id: 'HDP-1.2.2',
  345. state: 'INSTALLED'
  346. }
  347. }
  348. })
  349. },
  350. success: 'upgradeComponentSuccessCallback',
  351. error: 'ajaxErrorCallback'
  352. });
  353. });
  354. },
  355. /**
  356. * Success callback for upgrade host component request
  357. * @param {object} data
  358. * @param {object} opt
  359. * @param {object} params
  360. * @method upgradeComponentSuccessCallback
  361. */
  362. upgradeComponentSuccessCallback: function (data, opt, params) {
  363. console.log('Send request for UPGRADE successfully');
  364. if (App.get('testMode')) {
  365. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.starting, App.HostComponentStatus.started);
  366. }
  367. this.showBackgroundOperationsPopup();
  368. },
  369. /**
  370. * Send command to server to restart selected components
  371. * @param {object} event
  372. * @method restartComponent
  373. */
  374. restartComponent: function (event) {
  375. var component = event.context;
  376. return App.showConfirmationPopup(function () {
  377. batchUtils.restartHostComponents([component], Em.I18n.t('rollingrestart.context.selectedComponentOnSelectedHost').format(component.get('displayName')), "HOST_COMPONENT");
  378. });
  379. },
  380. /**
  381. * get current status of security settings,
  382. * if true security is enabled otherwise disabled
  383. * @return {Boolean}
  384. */
  385. securityEnabled: function () {
  386. return App.router.get('mainAdminSecurityController.securityEnabled');
  387. }.property('App.router.mainAdminSecurityController.securityEnabled'),
  388. /**
  389. * Send command to server to install selected host component
  390. * @param {object} event
  391. * @method addComponent
  392. */
  393. addComponent: function (event) {
  394. var self = this;
  395. var component = event.context;
  396. var componentName = component.get('componentName');
  397. var missedComponents = componentsUtils.checkComponentDependencies(componentName, {
  398. scope: 'host',
  399. installedComponents: this.get('content.hostComponents').mapProperty('componentName')
  400. });
  401. if (!!missedComponents.length) {
  402. var popupMessage = Em.I18n.t('host.host.addComponent.popup.dependedComponents.body').format(component.get('displayName'),
  403. stringUtils.getFormattedStringFromArray(missedComponents.map(function(cName) {
  404. return App.StackServiceComponent.find(cName).get('displayName');
  405. })));
  406. return App.showAlertPopup(Em.I18n.t('host.host.addComponent.popup.dependedComponents.header'), popupMessage);
  407. }
  408. if (componentName === 'ZOOKEEPER_SERVER' || componentName === 'HIVE_METASTORE') {
  409. return App.showConfirmationPopup(function () {
  410. self.primary(component);
  411. }, Em.I18n.t('hosts.host.addComponent.' + componentName ));
  412. } else {
  413. if (this.get('securityEnabled') && componentName !== 'CLIENTS') {
  414. return App.showConfirmationPopup(function () {
  415. self.primary(component);
  416. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName, self.get('content.hostName')));
  417. }
  418. else {
  419. return this.addClientComponent(component);
  420. }
  421. }
  422. },
  423. /**
  424. * Send command to server to install client on selected host
  425. * @param component
  426. */
  427. addClientComponent: function (component) {
  428. var self = this;
  429. var message = this.formatClientsMessage(component);
  430. return App.ModalPopup.show({
  431. primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'),
  432. header: Em.I18n.t('popup.confirmation.commonHeader'),
  433. addComponentMsg: function () {
  434. return Em.I18n.t('hosts.host.addComponent.msg').format(message);
  435. }.property(),
  436. bodyClass: Em.View.extend({
  437. templateName: require('templates/main/host/details/addComponentPopup')
  438. }),
  439. restartNagiosMsg: Em.View.extend({
  440. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(message))
  441. }),
  442. onPrimary: function () {
  443. this.hide();
  444. if (component.get('componentName') === 'CLIENTS') {
  445. // Clients component has many sub-components which
  446. // need to be installed.
  447. var scs = component.get('subComponentNames');
  448. scs.forEach(function (sc) {
  449. var c = Em.Object.create({
  450. displayName: App.format.role(sc),
  451. componentName: sc,
  452. serviceName: sc.replace("_CLIENT", "")
  453. });
  454. self.primary(c);
  455. });
  456. } else {
  457. self.primary(component);
  458. }
  459. }
  460. });
  461. },
  462. /**
  463. * format message for operation of adding clients
  464. * @param client
  465. */
  466. formatClientsMessage: function (client) {
  467. var displayName = Em.isNone(client.get('displayName')) ? '' : client.get('displayName');
  468. var subComponentNames = client.get('subComponentNames');
  469. if (subComponentNames && subComponentNames.length > 0) {
  470. var dns = [];
  471. subComponentNames.forEach(function (scn) {
  472. dns.push(App.format.role(scn));
  473. });
  474. displayName += " (" + dns.join(", ") + ")";
  475. }
  476. return displayName;
  477. },
  478. /**
  479. * Send request to add host component
  480. * @param {App.HostComponent} component
  481. * @method primary
  482. */
  483. primary: function (component) {
  484. var self = this;
  485. componentsUtils.installHostComponent(self.get('content.hostName'), component);
  486. },
  487. /**
  488. * Success callback for install host component request (sent in <code>addNewComponentSuccessCallback</code>)
  489. * @param {object} data
  490. * @param {object} opt
  491. * @param {object} params
  492. * @method installNewComponentSuccessCallback
  493. */
  494. installNewComponentSuccessCallback: function (data, opt, params) {
  495. if (!data.Requests || !data.Requests.id) {
  496. return false;
  497. }
  498. var self = this;
  499. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  500. if (App.get('testMode')) {
  501. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.installing, App.HostComponentStatus.stopped);
  502. }
  503. this.showBackgroundOperationsPopup(function () {
  504. if (params.componentName === 'ZOOKEEPER_SERVER' || params.componentName === 'HIVE_METASTORE') {
  505. self.set(params.componentName === 'ZOOKEEPER_SERVER' ? 'zkRequestId' : 'hiveRequestId', data.Requests.id);
  506. self.addObserver(
  507. 'App.router.backgroundOperationsController.serviceTimestamp',
  508. self,
  509. (params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs : self.checkHiveDone)
  510. );
  511. params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs() : self.checkHiveDone();
  512. }
  513. });
  514. return true;
  515. },
  516. /**
  517. * Call load tags
  518. * @method checkHiveDone
  519. */
  520. checkHiveDone: function () {
  521. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('hiveRequestId'));
  522. if (bg && !bg.get('isRunning')) {
  523. var self = this;
  524. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkHiveDone);
  525. setTimeout(function () {
  526. self.loadConfigs("loadHiveConfigs");
  527. }, App.get('componentsUpdateInterval'));
  528. }
  529. },
  530. /**
  531. * Success callback for load configs request
  532. * @param {object} data
  533. * @method loadHiveConfigs
  534. */
  535. loadHiveConfigs: function (data) {
  536. App.ajax.send({
  537. name: 'admin.get.all_configurations',
  538. sender: this,
  539. data: {
  540. urlParams: '(type=hive-site&tag=' + data.Clusters.desired_configs['hive-site'].tag + ')'
  541. },
  542. success: 'onLoadHiveConfigs'
  543. });
  544. },
  545. /**
  546. * update and save Hive hive.metastore.uris config to server
  547. * @param {object} data
  548. * @method onLoadHiveConfigs
  549. */
  550. onLoadHiveConfigs: function (data) {
  551. var hiveMSHosts = this.getHiveHosts();
  552. for (var i = 0; i < hiveMSHosts.length; i++) {
  553. hiveMSHosts[i] = "thrift://" + hiveMSHosts[i] + ":9083";
  554. }
  555. data.items[0].properties['hive.metastore.uris'] = hiveMSHosts.join(',');
  556. App.ajax.send({
  557. name: 'reassign.save_configs',
  558. sender: this,
  559. data: {
  560. siteName: 'hive-site',
  561. properties: data.items[0].properties,
  562. service_config_version_note: Em.I18n.t('hosts.host.hive.configs.save.note')
  563. }
  564. });
  565. },
  566. /**
  567. * Delete Hive Metastore is performed
  568. * @type {bool}
  569. */
  570. deleteHiveMetaStore: false,
  571. getHiveHosts: function () {
  572. var hiveHosts = App.HostComponent.find().filterProperty('componentName', 'HIVE_METASTORE').mapProperty('hostName');
  573. if (this.get('fromDeleteHost') || this.get('deleteHiveMetaStore')) {
  574. this.set('deleteHiveMetaStore', false);
  575. this.set('fromDeleteHost', false);
  576. return hiveHosts.without(this.get('content.hostName'));
  577. }
  578. return hiveHosts;
  579. },
  580. /**
  581. * Send command to server to resfresh configs of selected component
  582. * @param {object} event
  583. * @method refreshComponentConfigs
  584. */
  585. refreshComponentConfigs: function (event) {
  586. var self = this;
  587. return App.showConfirmationPopup(function () {
  588. var component = event.context;
  589. var context = Em.I18n.t('requestInfo.refreshComponentConfigs').format(component.get('displayName'));
  590. self.sendRefreshComponentConfigsCommand(component, context);
  591. });
  592. },
  593. /**
  594. * PUTs a command to server to refresh configs of host component.
  595. * @param {object} component
  596. * @param {object} context Context under which this command is beign sent.
  597. * @method sendRefreshComponentConfigsCommand
  598. */
  599. sendRefreshComponentConfigsCommand: function (component, context) {
  600. var resource_filters = [
  601. {
  602. service_name: component.get('service.serviceName'),
  603. component_name: component.get('componentName'),
  604. hosts: component.get('host.hostName')
  605. }
  606. ];
  607. App.ajax.send({
  608. name: 'host.host_component.refresh_configs',
  609. sender: this,
  610. data: {
  611. resource_filters: resource_filters,
  612. context: context
  613. },
  614. success: 'refreshComponentConfigsSuccessCallback'
  615. });
  616. },
  617. /**
  618. * Success callback for refresh host component configs request
  619. * @method refreshComponentConfigsSuccessCallback
  620. */
  621. refreshComponentConfigsSuccessCallback: function () {
  622. console.log('Send request for refresh configs successfully');
  623. this.showBackgroundOperationsPopup();
  624. },
  625. /**
  626. * Load tags
  627. * @method checkZkConfigs
  628. */
  629. checkZkConfigs: function () {
  630. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId'));
  631. if (bg && !bg.get('isRunning')) {
  632. var self = this;
  633. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs);
  634. setTimeout(function () {
  635. self.loadConfigs();
  636. }, App.get('componentsUpdateInterval'));
  637. }
  638. },
  639. /**
  640. * Load configs
  641. * @method loadConfigs
  642. */
  643. loadConfigs: function (callback) {
  644. App.ajax.send({
  645. name: 'config.tags',
  646. sender: this,
  647. success: callback ? callback : 'loadConfigsSuccessCallback'
  648. });
  649. },
  650. /**
  651. * Success callback for load configs request
  652. * @param {object} data
  653. * @method adConfigsSuccessCallback
  654. */
  655. loadConfigsSuccessCallback: function (data) {
  656. var urlParams = this.constructConfigUrlParams(data);
  657. if (urlParams.length > 0) {
  658. App.ajax.send({
  659. name: 'reassign.load_configs',
  660. sender: this,
  661. data: {
  662. urlParams: urlParams.join('|')
  663. },
  664. success: 'saveZkConfigs'
  665. });
  666. return true;
  667. }
  668. return false;
  669. },
  670. /**
  671. * construct URL params for query, that load configs
  672. * @param data {Object}
  673. * @return {Array}
  674. */
  675. constructConfigUrlParams: function (data) {
  676. var urlParams = [];
  677. var services = App.Service.find();
  678. if (App.get('isHaEnabled')) {
  679. urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
  680. }
  681. if (services.someProperty('serviceName', 'HBASE')) {
  682. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  683. }
  684. if (services.someProperty('serviceName', 'HIVE')) {
  685. urlParams.push('(type=webhcat-site&tag=' + data.Clusters.desired_configs['webhcat-site'].tag + ')');
  686. urlParams.push('(type=hive-site&tag=' + data.Clusters.desired_configs['hive-site'].tag + ')');
  687. }
  688. if (services.someProperty('serviceName', 'STORM')) {
  689. urlParams.push('(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')');
  690. }
  691. if ((services.someProperty('serviceName', 'YARN') && App.get('isHadoop22Stack')) || App.get('isRMHaEnabled')) {
  692. urlParams.push('(type=yarn-site&tag=' + data.Clusters.desired_configs['yarn-site'].tag + ')');
  693. }
  694. return urlParams;
  695. },
  696. /**
  697. * save new ZooKeeper configs to server
  698. * @param {object} data
  699. * @method saveZkConfigs
  700. */
  701. saveZkConfigs: function (data) {
  702. var configs = {};
  703. data.items.forEach(function (item) {
  704. configs[item.type] = item.properties;
  705. }, this);
  706. var zks = this.getZkServerHosts();
  707. var zksWithPort = this.concatZkNames(zks);
  708. this.setZKConfigs(configs, zksWithPort, zks);
  709. for (var site in configs) {
  710. if (!configs.hasOwnProperty(site)) continue;
  711. App.ajax.send({
  712. name: 'reassign.save_configs',
  713. sender: this,
  714. data: {
  715. siteName: site,
  716. properties: configs[site],
  717. service_config_version_note: Em.I18n.t('hosts.host.zooKeeper.configs.save.note')
  718. }
  719. });
  720. }
  721. },
  722. /**
  723. *
  724. * Set new values for some configs (based on available ZooKeeper Servers)
  725. * @param configs {object}
  726. * @param zksWithPort {string}
  727. * @param zks {array}
  728. * @return {Boolean}
  729. */
  730. setZKConfigs: function (configs, zksWithPort, zks) {
  731. if (typeof configs !== 'object' || !Array.isArray(zks)) return false;
  732. if (App.get('isHaEnabled')) {
  733. configs['core-site']['ha.zookeeper.quorum'] = zksWithPort;
  734. }
  735. if (configs['hbase-site']) {
  736. configs['hbase-site']['hbase.zookeeper.quorum'] = zks.join(',');
  737. }
  738. if (configs['webhcat-site']) {
  739. configs['webhcat-site']['templeton.zookeeper.hosts'] = zksWithPort;
  740. }
  741. if (configs['hive-site']) {
  742. configs['hive-site']['hive.cluster.delegation.token.store.zookeeper.connectString'] = zksWithPort;
  743. }
  744. if (configs['storm-site']) {
  745. configs['storm-site']['storm.zookeeper.servers'] = JSON.stringify(zks).replace(/"/g, "'");
  746. }
  747. if (App.get('isRMHaEnabled')) {
  748. configs['yarn-site']['yarn.resourcemanager.zk-address'] = zks.join(',');
  749. }
  750. if (App.get('isHadoop22Stack')) {
  751. if (configs['hive-site']) {
  752. configs['hive-site']['hive.zookeeper.quorum'] = zksWithPort;
  753. }
  754. if (configs['yarn-site']) {
  755. configs['yarn-site']['hadoop.registry.zk.quorum'] = zksWithPort;
  756. }
  757. }
  758. return true;
  759. },
  760. /**
  761. * concatenate URLs to ZOOKEEPER hosts with port "2181",
  762. * as value of config divided by comma
  763. * @param zks {array}
  764. */
  765. concatZkNames: function (zks) {
  766. var zks_with_port = '';
  767. zks.forEach(function (zk) {
  768. zks_with_port += zk + ':2181,';
  769. });
  770. return zks_with_port.slice(0, -1);
  771. },
  772. /**
  773. * Is deleteHost action id fired
  774. * @type {bool}
  775. */
  776. fromDeleteHost: false,
  777. /**
  778. * Is ZooKeeper Server being deleted from host
  779. * @type {bool}
  780. */
  781. fromDeleteZkServer: false,
  782. /**
  783. * Get list of hostnames where ZK Server is installed
  784. * @returns {string[]}
  785. * @method getZkServerHosts
  786. */
  787. getZkServerHosts: function () {
  788. var zks = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('hostName');
  789. if (this.get('fromDeleteHost') || this.get('fromDeleteZkServer')) {
  790. this.set('fromDeleteHost', false);
  791. this.set('fromDeleteZkServer', false);
  792. return zks.without(this.get('content.hostName'));
  793. }
  794. return zks;
  795. },
  796. /**
  797. * Send command to server to install selected host component
  798. * @param {Object} event
  799. * @method installComponent
  800. */
  801. installComponent: function (event) {
  802. var self = this;
  803. var component = event.context;
  804. var componentName = component.get('componentName');
  805. var displayName = component.get('displayName');
  806. return App.ModalPopup.show({
  807. primary: Em.I18n.t('hosts.host.installComponent.popup.confirm'),
  808. header: Em.I18n.t('popup.confirmation.commonHeader'),
  809. installComponentMessage: function () {
  810. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  811. }.property(),
  812. restartNagiosMsg: Em.View.extend({
  813. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(displayName))
  814. }),
  815. bodyClass: Em.View.extend({
  816. templateName: require('templates/main/host/details/installComponentPopup')
  817. }),
  818. onPrimary: function () {
  819. this.hide();
  820. App.ajax.send({
  821. name: 'common.host.host_component.update',
  822. sender: self,
  823. data: {
  824. hostName: self.get('content.hostName'),
  825. serviceName: component.get('service.serviceName'),
  826. componentName: componentName,
  827. component: component,
  828. context: Em.I18n.t('requestInfo.installHostComponent') + " " + displayName,
  829. HostRoles: {
  830. state: 'INSTALLED'
  831. }
  832. },
  833. success: 'installComponentSuccessCallback',
  834. error: 'ajaxErrorCallback'
  835. });
  836. }
  837. });
  838. },
  839. /**
  840. * Success callback for install component request
  841. * @param {object} data
  842. * @param {object} opt
  843. * @param {object} params
  844. * @method installComponentSuccessCallback
  845. */
  846. installComponentSuccessCallback: function (data, opt, params) {
  847. console.log('Send request for REINSTALL COMPONENT successfully');
  848. if (App.get('testMode')) {
  849. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.installing, App.HostComponentStatus.stopped);
  850. }
  851. this.showBackgroundOperationsPopup();
  852. },
  853. /**
  854. * Send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
  855. * @param {App.HostComponent} component
  856. * @method decommission
  857. */
  858. decommission: function (component) {
  859. var self = this;
  860. return App.showConfirmationPopup(function () {
  861. self.runDecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
  862. });
  863. },
  864. /**
  865. * identify correct component to run decommission on them by service name,
  866. * in result run proper decommission method
  867. * @param hostName
  868. * @param svcName
  869. */
  870. runDecommission: function (hostName, svcName) {
  871. switch (svcName) {
  872. case 'HDFS':
  873. this.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
  874. break;
  875. case 'YARN':
  876. this.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  877. break;
  878. case 'MAPREDUCE':
  879. this.doDecommission(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  880. break;
  881. case 'HBASE':
  882. this.warnBeforeDecommission(hostName);
  883. }
  884. },
  885. /**
  886. * Send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
  887. * @param {App.HostComponent} component
  888. * @method recommission
  889. */
  890. recommission: function (component) {
  891. var self = this;
  892. return App.showConfirmationPopup(function () {
  893. self.runRecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
  894. });
  895. },
  896. /**
  897. * identify correct component to run recommission on them by service name,
  898. * in result run proper recommission method
  899. * @param hostName
  900. * @param svcName
  901. */
  902. runRecommission: function (hostName, svcName) {
  903. switch (svcName) {
  904. case 'HDFS':
  905. this.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE");
  906. break;
  907. case 'YARN':
  908. this.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  909. break;
  910. case 'MAPREDUCE':
  911. this.doRecommissionAndRestart(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  912. break;
  913. case 'HBASE':
  914. this.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  915. }
  916. this.showBackgroundOperationsPopup();
  917. },
  918. /**
  919. * Performs Decommission (for DN, TT and NM)
  920. * @param {string} hostName
  921. * @param {string} serviceName
  922. * @param {string} componentName
  923. * @param {string} slaveType
  924. * @method doDecommission
  925. */
  926. doDecommission: function (hostName, serviceName, componentName, slaveType) {
  927. var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
  928. var context = Em.I18n.t(contextNameString);
  929. App.ajax.send({
  930. name: 'host.host_component.decommission_slave',
  931. sender: this,
  932. data: {
  933. context: context,
  934. command: 'DECOMMISSION',
  935. hostName: hostName,
  936. serviceName: serviceName,
  937. componentName: componentName,
  938. slaveType: slaveType
  939. },
  940. success: 'decommissionSuccessCallback',
  941. error: 'decommissionErrorCallback'
  942. });
  943. },
  944. /**
  945. * check is hbase regionserver in mm. If so - run decommission
  946. * otherwise shows warning
  947. * @method warnBeforeDecommission
  948. * @param {string} hostNames - list of host when run from bulk operations or current host
  949. */
  950. warnBeforeDecommission: function (hostNames) {
  951. if (this.get('content.hostComponents').findProperty('componentName', 'HBASE_REGIONSERVER').get('passiveState') == "OFF") {
  952. this.showHbaseActiveWarning();
  953. } else {
  954. this.checkRegionServerState(hostNames);
  955. }
  956. },
  957. /**
  958. * send call to check is this regionserver last in cluster which has desired_admin_state property "INSERVICE"
  959. * @method checkRegionServerState
  960. * @param hostNames
  961. */
  962. checkRegionServerState: function (hostNames) {
  963. return App.ajax.send({
  964. name: 'host.region_servers.in_inservice',
  965. sender: this,
  966. data: {
  967. hostNames: hostNames
  968. },
  969. success: 'checkRegionServerStateSuccessCallback'
  970. });
  971. },
  972. /**
  973. * check is this regionserver last in cluster which has desired_admin_state property "INSERVICE"
  974. * @method checkRegionServerStateSuccessCallback
  975. * @param data
  976. * @param opt
  977. * @param params
  978. */
  979. checkRegionServerStateSuccessCallback: function (data, opt, params) {
  980. var hostArray = params.hostNames.split(",");
  981. var decommissionPossible = (data.items.mapProperty('HostRoles.host_name').filter(function (hostName) {
  982. return !hostArray.contains(hostName);
  983. }, this).length >= 1);
  984. if (decommissionPossible) {
  985. this.doDecommissionRegionServer(params.hostNames, "HBASE", "HBASE_MASTER", "HBASE_REGIONSERVER");
  986. } else {
  987. this.showRegionServerWarning();
  988. }
  989. },
  990. /**
  991. * show warning that regionserver is last in cluster which has desired_admin_state property "INSERVICE"
  992. * @method showRegionServerWarning
  993. * @param hostNames
  994. */
  995. showRegionServerWarning: function () {
  996. return App.ModalPopup.show({
  997. header: Em.I18n.t('common.warning'),
  998. message: Em.I18n.t('hosts.host.hbase_regionserver.decommission.warning'),
  999. bodyClass: Ember.View.extend({
  1000. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  1001. }),
  1002. secondary: false
  1003. });
  1004. },
  1005. /**
  1006. * shows warning: put hbase regionserver in passive state
  1007. * @method showHbaseActiveWarning
  1008. * @return {App.ModalPopup}
  1009. */
  1010. showHbaseActiveWarning: function () {
  1011. return App.ModalPopup.show({
  1012. header: Em.I18n.t('common.warning'),
  1013. message: function () {
  1014. return Em.I18n.t('hostPopup.recommendation.beforeDecommission').format(App.format.components["HBASE_REGIONSERVER"]);
  1015. }.property(),
  1016. bodyClass: Ember.View.extend({
  1017. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  1018. }),
  1019. secondary: false
  1020. });
  1021. },
  1022. /**
  1023. * Performs Decommission (for RegionServer)
  1024. * @method doDecommissionRegionServer
  1025. * @param {string} hostNames - list of host when run from bulk operations or current host
  1026. * @param {string} serviceName - serviceName
  1027. * @param {string} componentName - master compoent name
  1028. * @param {string} slaveType - slave component name
  1029. */
  1030. doDecommissionRegionServer: function (hostNames, serviceName, componentName, slaveType) {
  1031. var batches = [
  1032. {
  1033. "order_id": 1,
  1034. "type": "POST",
  1035. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/requests",
  1036. "RequestBodyInfo": {
  1037. "RequestInfo": {
  1038. "context": Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  1039. "command": "DECOMMISSION",
  1040. "exclusive" :"true",
  1041. "parameters": {
  1042. "slave_type": slaveType,
  1043. "excluded_hosts": hostNames
  1044. },
  1045. 'operation_level': {
  1046. level: "HOST_COMPONENT",
  1047. cluster_name: App.get('clusterName'),
  1048. host_name: hostNames,
  1049. service_name: serviceName
  1050. }
  1051. },
  1052. "Requests/resource_filters": [
  1053. {"service_name": serviceName, "component_name": componentName}
  1054. ]
  1055. }
  1056. }];
  1057. var id = 2;
  1058. var hAray = hostNames.split(",");
  1059. for (var i = 0; i < hAray.length; i++) {
  1060. batches.push({
  1061. "order_id": id,
  1062. "type": "PUT",
  1063. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hAray[i] + "/host_components/" + slaveType,
  1064. "RequestBodyInfo": {
  1065. "RequestInfo": {
  1066. context: Em.I18n.t('hosts.host.regionserver.decommission.batch2'),
  1067. exclusive: true,
  1068. operation_level: {
  1069. level: "HOST_COMPONENT",
  1070. cluster_name: App.get('clusterName'),
  1071. host_name: hostNames,
  1072. service_name: serviceName || null
  1073. }
  1074. },
  1075. "Body": {
  1076. HostRoles: {
  1077. state: "INSTALLED"
  1078. }
  1079. }
  1080. }
  1081. });
  1082. id++;
  1083. }
  1084. batches.push({
  1085. "order_id": id,
  1086. "type": "POST",
  1087. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/requests",
  1088. "RequestBodyInfo": {
  1089. "RequestInfo": {
  1090. "context": Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  1091. "command": "DECOMMISSION",
  1092. "service_name": serviceName,
  1093. "component_name": componentName,
  1094. "parameters": {
  1095. "slave_type": slaveType,
  1096. "excluded_hosts": hostNames,
  1097. "mark_draining_only": true
  1098. },
  1099. 'operation_level': {
  1100. level: "HOST_COMPONENT",
  1101. cluster_name: App.get('clusterName'),
  1102. host_name: hostNames,
  1103. service_name: serviceName
  1104. }
  1105. },
  1106. "Requests/resource_filters": [
  1107. {"service_name": serviceName, "component_name": componentName}
  1108. ]
  1109. }
  1110. });
  1111. App.ajax.send({
  1112. name: 'host.host_component.recommission_and_restart',
  1113. sender: this,
  1114. data: {
  1115. intervalTimeSeconds: 1,
  1116. tolerateSize: 0,
  1117. batches: batches
  1118. },
  1119. success: 'decommissionSuccessCallback',
  1120. error: 'decommissionErrorCallback'
  1121. });
  1122. },
  1123. /**
  1124. * Error callback for decommission requests
  1125. * @param {object} request
  1126. * @param {object} ajaxOptions
  1127. * @param {string} error
  1128. * @method decommissionErrorCallback
  1129. */
  1130. decommissionErrorCallback: function (request, ajaxOptions, error) {
  1131. console.log('ERROR: ' + error);
  1132. },
  1133. /**
  1134. * Success ajax response for Recommission/Decommission slaves
  1135. * @param {object} data
  1136. * @method decommissionSuccessCallback
  1137. * @return {Boolean}
  1138. */
  1139. decommissionSuccessCallback: function (data) {
  1140. if (data && (data.Requests || data.resources[0].RequestSchedule)) {
  1141. this.showBackgroundOperationsPopup();
  1142. return true;
  1143. } else {
  1144. console.log('cannot get request id from ', data);
  1145. return false;
  1146. }
  1147. },
  1148. /**
  1149. * Performs Recommission and Start
  1150. * @param {string} hostNames
  1151. * @param {string} serviceName
  1152. * @param {string} componentName
  1153. * @param {string} slaveType
  1154. * @method doRecommissionAndStart
  1155. */
  1156. doRecommissionAndStart: function (hostNames, serviceName, componentName, slaveType) {
  1157. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  1158. var context_1 = Em.I18n.t(contextNameString_1);
  1159. var contextNameString_2 = 'requestInfo.startHostComponent.' + slaveType.toLowerCase();
  1160. var startContext = Em.I18n.t(contextNameString_2);
  1161. var params = {
  1162. "slave_type": slaveType,
  1163. "included_hosts": hostNames
  1164. };
  1165. if (serviceName == "HBASE") {
  1166. params.mark_draining_only = true;
  1167. }
  1168. var batches = [
  1169. {
  1170. "order_id": 1,
  1171. "type": "POST",
  1172. "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1173. "RequestBodyInfo": {
  1174. "RequestInfo": {
  1175. "context": context_1,
  1176. "command": "DECOMMISSION",
  1177. "exclusive":"true",
  1178. "parameters": params,
  1179. 'operation_level': {
  1180. level: "HOST_COMPONENT",
  1181. cluster_name: App.get('clusterName'),
  1182. host_name: hostNames,
  1183. service_name: serviceName
  1184. }
  1185. },
  1186. "Requests/resource_filters": [
  1187. {"service_name": serviceName, "component_name": componentName}
  1188. ]
  1189. }
  1190. }];
  1191. var id = 2;
  1192. var hAray = hostNames.split(",");
  1193. for (var i = 0; i < hAray.length; i++) {
  1194. batches.push( {
  1195. "order_id": id,
  1196. "type": "PUT",
  1197. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hAray[i] + "/host_components/" + slaveType,
  1198. "RequestBodyInfo": {
  1199. "RequestInfo": {
  1200. context: startContext,
  1201. operation_level: {
  1202. level: "HOST_COMPONENT",
  1203. cluster_name: App.get('clusterName'),
  1204. host_name: hostNames,
  1205. service_name: serviceName || null
  1206. }
  1207. },
  1208. "Body": {
  1209. HostRoles: {
  1210. state: "STARTED"
  1211. }
  1212. }
  1213. }
  1214. });
  1215. id++;
  1216. }
  1217. App.ajax.send({
  1218. name: 'host.host_component.recommission_and_restart',
  1219. sender: this,
  1220. data: {
  1221. intervalTimeSeconds: 1,
  1222. tolerateSize: 1,
  1223. batches: batches
  1224. },
  1225. success: 'decommissionSuccessCallback',
  1226. error: 'decommissionErrorCallback'
  1227. });
  1228. },
  1229. /**
  1230. * Performs Recommission and Restart
  1231. * @param {string} hostNames
  1232. * @param {string} serviceName
  1233. * @param {string} componentName
  1234. * @param {string} slaveType
  1235. * @method doRecommissionAndStart
  1236. */
  1237. doRecommissionAndRestart: function (hostNames, serviceName, componentName, slaveType) {
  1238. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  1239. var context_1 = Em.I18n.t(contextNameString_1);
  1240. var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
  1241. var context_2 = Em.I18n.t(contextNameString_2);
  1242. App.ajax.send({
  1243. name: 'host.host_component.recommission_and_restart',
  1244. sender: this,
  1245. data: {
  1246. intervalTimeSeconds: 1,
  1247. tolerateSize: 1,
  1248. batches: [
  1249. {
  1250. "order_id": 1,
  1251. "type": "POST",
  1252. "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1253. "RequestBodyInfo": {
  1254. "RequestInfo": {
  1255. "context": context_1,
  1256. "command": "DECOMMISSION",
  1257. "exclusive":"true",
  1258. "parameters": {
  1259. "slave_type": slaveType,
  1260. "included_hosts": hostNames
  1261. },
  1262. 'operation_level': {
  1263. level: "HOST_COMPONENT",
  1264. cluster_name: App.get('clusterName'),
  1265. host_name: hostNames,
  1266. service_name: serviceName
  1267. }
  1268. },
  1269. "Requests/resource_filters": [
  1270. {"service_name": serviceName, "component_name": componentName}
  1271. ]
  1272. }
  1273. },
  1274. {
  1275. "order_id": 2,
  1276. "type": "POST",
  1277. "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1278. "RequestBodyInfo": {
  1279. "RequestInfo": {
  1280. "context": context_2,
  1281. "command": "RESTART",
  1282. "service_name": serviceName,
  1283. "component_name": slaveType,
  1284. "exclusive":"true",
  1285. "hosts": hostNames
  1286. }
  1287. }
  1288. }
  1289. ]
  1290. },
  1291. success: 'decommissionSuccessCallback',
  1292. error: 'decommissionErrorCallback'
  1293. });
  1294. },
  1295. /**
  1296. * Handler for host-menu items actions
  1297. * @param {object} option
  1298. * @method doAction
  1299. */
  1300. doAction: function (option) {
  1301. switch (option.context.action) {
  1302. case "deleteHost":
  1303. this.validateAndDeleteHost();
  1304. break;
  1305. case "startAllComponents":
  1306. if (!this.get('content.isNotHeartBeating')) this.doStartAllComponents();
  1307. break;
  1308. case "stopAllComponents":
  1309. if (!this.get('content.isNotHeartBeating')) this.doStopAllComponents();
  1310. break;
  1311. case "restartAllComponents":
  1312. if (!this.get('content.isNotHeartBeating')) this.doRestartAllComponents();
  1313. break;
  1314. case "onOffPassiveModeForHost":
  1315. this.onOffPassiveModeForHost(option.context);
  1316. break;
  1317. }
  1318. },
  1319. /**
  1320. * Turn On/Off Passive Mode for host
  1321. * @param {object} context
  1322. * @method onOffPassiveModeForHost
  1323. */
  1324. onOffPassiveModeForHost: function (context) {
  1325. var state = context.active ? 'ON' : 'OFF';
  1326. var self = this;
  1327. var message = Em.I18n.t('hosts.host.details.for.postfix').format(context.label);
  1328. return App.showConfirmationPopup(function () {
  1329. self.hostPassiveModeRequest(state, message);
  1330. },
  1331. Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off', this.get('content.hostName'))
  1332. );
  1333. },
  1334. /**
  1335. * Send request to get passive state for host
  1336. * @param {string} state
  1337. * @param {string} message
  1338. * @method hostPassiveModeRequest
  1339. */
  1340. hostPassiveModeRequest: function (state, message) {
  1341. App.ajax.send({
  1342. name: 'bulk_request.hosts.passive_state',
  1343. sender: this,
  1344. data: {
  1345. hostNames: this.get('content.hostName'),
  1346. passive_state: state,
  1347. requestInfo: message
  1348. },
  1349. success: 'updateHost'
  1350. });
  1351. },
  1352. /**
  1353. * Success callback for receiving host passive state
  1354. * @param {object} data
  1355. * @param {object} opt
  1356. * @param {object} params
  1357. * @method updateHost
  1358. */
  1359. updateHost: function (data, opt, params) {
  1360. this.set('content.passiveState', params.passive_state);
  1361. batchUtils.infoPassiveState(params.passive_state);
  1362. },
  1363. /**
  1364. * Send request to get passive state for hostComponent
  1365. * @param {object} component - hostComponentn object
  1366. * @param {string} state
  1367. * @param {string} message
  1368. * @method hostPassiveModeRequest
  1369. */
  1370. updateComponentPassiveState: function (component, state, message) {
  1371. App.ajax.send({
  1372. name: 'common.host.host_component.passive',
  1373. sender: this,
  1374. data: {
  1375. hostName: this.get('content.hostName'),
  1376. componentName: component.get('componentName'),
  1377. component: component,
  1378. passive_state: state,
  1379. context: message
  1380. },
  1381. success: 'updateHostComponent'
  1382. });
  1383. },
  1384. /**
  1385. * Success callback for receiving hostComponent passive state
  1386. * @param {object} data
  1387. * @param {object} opt
  1388. * @param {object} params
  1389. * @method updateHost
  1390. */
  1391. updateHostComponent: function (data, opt, params) {
  1392. params.component.set('passiveState', params.passive_state);
  1393. batchUtils.infoPassiveState(params.passive_state);
  1394. },
  1395. /**
  1396. * Show confirmation popup for action "start all components"
  1397. * @method doStartAllComponents
  1398. */
  1399. doStartAllComponents: function () {
  1400. var self = this;
  1401. var components = this.get('serviceNonClientActiveComponents');
  1402. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1403. if (componentsLength > 0) {
  1404. return App.showConfirmationPopup(function () {
  1405. self.sendComponentCommand(components, Em.I18n.t('hosts.host.maintainance.startAllComponents.context'), App.HostComponentStatus.started);
  1406. });
  1407. }
  1408. },
  1409. /**
  1410. * Show confirmation popup for action "stop all components"
  1411. * @method doStopAllComponents
  1412. */
  1413. doStopAllComponents: function () {
  1414. var self = this;
  1415. var components = this.get('serviceNonClientActiveComponents');
  1416. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1417. if (componentsLength > 0) {
  1418. return App.showConfirmationPopup(function () {
  1419. self.sendComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'), App.HostComponentStatus.stopped);
  1420. });
  1421. }
  1422. },
  1423. /**
  1424. * Show confirmation popup for action "restart all components"
  1425. * @method doRestartAllComponents
  1426. */
  1427. doRestartAllComponents: function () {
  1428. var self = this;
  1429. var components = this.get('serviceActiveComponents');
  1430. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1431. if (componentsLength > 0) {
  1432. return App.showConfirmationPopup(function () {
  1433. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')), "HOST");
  1434. });
  1435. }
  1436. },
  1437. /**
  1438. * get info about host-components, exactly:
  1439. * - host-components grouped by status, features
  1440. * - flag, that indicate whether ZooKeeper Server is installed
  1441. * @return {Object}
  1442. */
  1443. getHostComponentsInfo: function () {
  1444. var componentsOnHost = this.get('content.hostComponents');
  1445. var allComponents = App.HostComponent.find();
  1446. var stoppedStates = [App.HostComponentStatus.stopped,
  1447. App.HostComponentStatus.install_failed,
  1448. App.HostComponentStatus.upgrade_failed,
  1449. App.HostComponentStatus.init,
  1450. App.HostComponentStatus.unknown];
  1451. var container = {
  1452. zkServerInstalled: false,
  1453. lastComponents: [],
  1454. masterComponents: [],
  1455. runningComponents: [],
  1456. notDecommissionedComponents: [],
  1457. nonDeletableComponents: [],
  1458. unknownComponents: []
  1459. };
  1460. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  1461. componentsOnHost.forEach(function (cInstance) {
  1462. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  1463. container.zkServerInstalled = true;
  1464. }
  1465. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  1466. container.lastComponents.push(cInstance.get('displayName'));
  1467. }
  1468. var workStatus = cInstance.get('workStatus');
  1469. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  1470. container.masterComponents.push(cInstance.get('displayName'));
  1471. }
  1472. if (stoppedStates.indexOf(workStatus) < 0) {
  1473. container.runningComponents.push(cInstance.get('displayName'));
  1474. }
  1475. if (!cInstance.get('isDeletable')) {
  1476. container.nonDeletableComponents.push(cInstance.get('displayName'));
  1477. }
  1478. if (workStatus === App.HostComponentStatus.unknown) {
  1479. container.unknownComponents.push(cInstance.get('displayName'));
  1480. }
  1481. if (cInstance.get('adminState') === 'INSERVICE') {
  1482. container.notDecommissionedComponents.push(cInstance.get('displayName'));
  1483. }
  1484. });
  1485. }
  1486. return container;
  1487. },
  1488. /**
  1489. * Deletion of hosts not supported for this version
  1490. * @method validateAndDeleteHost
  1491. */
  1492. validateAndDeleteHost: function () {
  1493. var container = this.getHostComponentsInfo();
  1494. if (container.masterComponents.length > 0) {
  1495. this.raiseDeleteComponentsError(container.masterComponents, 'masterList');
  1496. return;
  1497. } else if (container.nonDeletableComponents.length > 0) {
  1498. this.raiseDeleteComponentsError(container.nonDeletableComponents, 'nonDeletableList');
  1499. return;
  1500. } else if (container.runningComponents.length + container.notDecommissionedComponents.length > 0) {
  1501. this.raiseDeleteComponentsError(container.runningComponents, 'runningList');
  1502. return;
  1503. }
  1504. if (container.zkServerInstalled) {
  1505. var self = this;
  1506. return App.showConfirmationPopup(function () {
  1507. self.confirmDeleteHost(container.unknownComponents, container.lastComponents);
  1508. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1509. } else {
  1510. this.confirmDeleteHost(container.unknownComponents, container.lastComponents);
  1511. }
  1512. },
  1513. /**
  1514. * Show popup with info about reasons why host can't be deleted
  1515. * @param {Array} components
  1516. * @param {string} type
  1517. * @method raiseDeleteComponentsError
  1518. */
  1519. raiseDeleteComponentsError: function (components, type) {
  1520. App.ModalPopup.show({
  1521. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1522. type: type,
  1523. showBodyEnd: function () {
  1524. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1525. }.property(),
  1526. components: components,
  1527. componentsStr: function () {
  1528. return this.get('components').join(", ");
  1529. }.property(),
  1530. componentsBody: function () {
  1531. var componentsLength = this.get('components.length');
  1532. return componentsLength ? Em.I18n.t('hosts.cant.do.popup.' + type + '.body').format(this.get('components').length) : '';
  1533. }.property(),
  1534. componentsBodyEnd: function () {
  1535. if (this.get('showBodyEnd')) {
  1536. return Em.I18n.t('hosts.cant.do.popup.' + type + '.body.end');
  1537. }
  1538. return '';
  1539. }.property(),
  1540. bodyClass: Em.View.extend({
  1541. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1542. }),
  1543. secondary: null
  1544. });
  1545. },
  1546. /**
  1547. * Show confirmation popup to delete host
  1548. * @param {string[]} unknownComponents
  1549. * @param {string[]} lastComponents
  1550. * @method confirmDeleteHost
  1551. */
  1552. confirmDeleteHost: function (unknownComponents, lastComponents) {
  1553. var self = this;
  1554. return App.ModalPopup.show({
  1555. header: Em.I18n.t('hosts.delete.popup.title'),
  1556. deletePopupBody: function () {
  1557. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1558. }.property(),
  1559. lastComponent: function () {
  1560. if (lastComponents && lastComponents.length) {
  1561. this.set('isChecked', false);
  1562. return true;
  1563. } else {
  1564. this.set('isChecked', true);
  1565. return false;
  1566. }
  1567. }.property(),
  1568. disablePrimary: function () {
  1569. return !this.get('isChecked');
  1570. }.property('isChecked'),
  1571. isChecked: false,
  1572. lastComponentError: Em.View.extend({
  1573. template: Em.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  1574. }),
  1575. unknownComponents: function () {
  1576. if (unknownComponents && unknownComponents.length) {
  1577. return unknownComponents.join(", ");
  1578. }
  1579. return '';
  1580. }.property(),
  1581. bodyClass: Em.View.extend({
  1582. templateName: require('templates/main/host/details/doDeleteHostPopup')
  1583. }),
  1584. onPrimary: function () {
  1585. var popup = this;
  1586. var completeCallback = function () {
  1587. popup.hide();
  1588. };
  1589. self.doDeleteHost(completeCallback);
  1590. }
  1591. });
  1592. },
  1593. /**
  1594. * send DELETE calls to components of host and after delete host itself
  1595. * @param completeCallback
  1596. * @method doDeleteHost
  1597. */
  1598. doDeleteHost: function (completeCallback) {
  1599. this.set('fromDeleteHost', true);
  1600. var allComponents = this.get('content.hostComponents');
  1601. var deleteError = null;
  1602. var dfd = $.Deferred();
  1603. var self = this;
  1604. if (allComponents.get('length') > 0) {
  1605. allComponents.forEach(function (component, index) {
  1606. var length = allComponents.get('length');
  1607. if (!deleteError) {
  1608. this._doDeleteHostComponent(component, function () {
  1609. deleteError = self.get('_deletedHostComponentResult');
  1610. if (index == length - 1) {
  1611. dfd.resolve();
  1612. }
  1613. });
  1614. }
  1615. }, this);
  1616. } else {
  1617. dfd.resolve();
  1618. }
  1619. dfd.done(function () {
  1620. if (!deleteError) {
  1621. App.ajax.send({
  1622. name: 'common.delete.host',
  1623. sender: self,
  1624. data: {
  1625. hostName: self.get('content.hostName')
  1626. },
  1627. callback: completeCallback,
  1628. success: 'deleteHostSuccessCallback',
  1629. error: 'deleteHostErrorCallback'
  1630. });
  1631. }
  1632. else {
  1633. completeCallback();
  1634. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  1635. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  1636. }
  1637. });
  1638. },
  1639. deleteHostSuccessCallback: function (data) {
  1640. var self = this;
  1641. App.router.get('updateController').updateHost(function () {
  1642. self.loadConfigs('loadHiveConfigs');
  1643. self.loadConfigs();
  1644. App.router.transitionTo('hosts.index');
  1645. });
  1646. App.router.get('clusterController').getAllHostNames();
  1647. },
  1648. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  1649. console.log('Error deleting host.');
  1650. console.log(textStatus);
  1651. console.log(errorThrown);
  1652. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  1653. this.loadConfigs();
  1654. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  1655. },
  1656. /**
  1657. * Send command to server to restart all host components with stale configs
  1658. * @method restartAllStaleConfigComponents
  1659. */
  1660. restartAllStaleConfigComponents: function () {
  1661. var self = this;
  1662. return App.showConfirmationPopup(function () {
  1663. var staleComponents = self.get('content.componentsWithStaleConfigs');
  1664. batchUtils.restartHostComponents(staleComponents, Em.I18n.t('rollingrestart.context.allWithStaleConfigsOnSelectedHost').format(self.get('content.hostName')), "HOST");
  1665. });
  1666. },
  1667. /**
  1668. * open Reassign Master Wizard with selected component
  1669. * @param {object} event
  1670. * @method moveComponent
  1671. */
  1672. moveComponent: function (event) {
  1673. return App.showConfirmationPopup(function () {
  1674. var component = event.context;
  1675. var reassignMasterController = App.router.get('reassignMasterController');
  1676. reassignMasterController.saveComponentToReassign(component);
  1677. reassignMasterController.getSecurityStatus();
  1678. reassignMasterController.setCurrentStep('1');
  1679. App.router.transitionTo('reassign');
  1680. });
  1681. },
  1682. /**
  1683. * Restart clients host components to apply config changes
  1684. * @param {object} event
  1685. * @method refreshConfigs
  1686. */
  1687. refreshConfigs: function (event) {
  1688. var self = this;
  1689. var components = event.context.filter(function (component) {
  1690. return component.get('staleConfigs');
  1691. });
  1692. if (components.get('length') > 0) {
  1693. return App.showConfirmationPopup(function () {
  1694. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allClientsOnSelectedHost').format(self.get('content.hostName')), "HOST");
  1695. });
  1696. }
  1697. },
  1698. toggleMaintenanceMode: function (event) {
  1699. var self = this;
  1700. var state = event.context.get('passiveState') === "ON" ? "OFF" : "ON";
  1701. var message = Em.I18n.t('passiveState.turn' + state.toCapital() + 'For').format(event.context.get('displayName'));
  1702. return App.showConfirmationPopup(function () {
  1703. self.updateComponentPassiveState(event.context, state, message);
  1704. });
  1705. },
  1706. downloadClientConfigs: function (event) {
  1707. componentsUtils.downloadClientConfigs.call(this, {
  1708. hostName: event.context.get('hostName'),
  1709. componentName: event.context.get('componentName'),
  1710. displayName: event.context.get('displayName')
  1711. });
  1712. },
  1713. reinstallClients: function(event) {
  1714. var clientsToInstall = event.context.filter(function(component) {
  1715. return ['INIT', 'INSTALL_FAILED'].contains(component.get('workStatus'));
  1716. });
  1717. if (!clientsToInstall.length) return;
  1718. this.sendComponentCommand(clientsToInstall, Em.I18n.t('host.host.details.installClients'), 'INSTALLED');
  1719. },
  1720. /**
  1721. * On click handler for custom command from items menu
  1722. * @param context
  1723. */
  1724. executeCustomCommand: function(event) {
  1725. var controller = this;
  1726. var context = event.context;
  1727. return App.showConfirmationPopup(function() {
  1728. App.ajax.send({
  1729. name : 'service.item.executeCustomCommand',
  1730. sender: controller,
  1731. data : {
  1732. command : context.command,
  1733. context : Em.I18n.t('services.service.actions.run.executeCustomCommand.context').format(context.command),
  1734. hosts : context.hosts,
  1735. serviceName : context.service,
  1736. componentName : context.component
  1737. },
  1738. success : 'executeCustomCommandSuccessCallback',
  1739. error : 'executeCustomCommandErrorCallback'
  1740. });
  1741. });
  1742. },
  1743. executeCustomCommandSuccessCallback : function(data, ajaxOptions, params) {
  1744. if (data.Requests.id) {
  1745. App.router.get('backgroundOperationsController').showPopup();
  1746. } else {
  1747. console.warn('Error during execution of ' + params.command + ' custom command on' + params.componentName);
  1748. }
  1749. },
  1750. executeCustomCommandErrorCallback : function(data) {
  1751. var error = Em.I18n.t('services.service.actions.run.executeCustomCommand.error');
  1752. if(data && data.responseText){
  1753. try {
  1754. var json = $.parseJSON(data.responseText);
  1755. error += json.message;
  1756. } catch (err) {}
  1757. }
  1758. App.showAlertPopup(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), error);
  1759. console.warn('Error during executing custom command');
  1760. },
  1761. /**
  1762. * install HostStackVersion on host
  1763. * @param {object} event
  1764. */
  1765. installVersion: function (event) {
  1766. App.ajax.send({
  1767. name: 'host.stack_versions.install',
  1768. sender: this,
  1769. data: {
  1770. hostName: this.get('content.hostName'),
  1771. version: event.context
  1772. },
  1773. success: 'installVersionSuccessCallback'
  1774. });
  1775. },
  1776. /**
  1777. * success callback of <code>installVersion</code>
  1778. * on success set version status to INSTALLING
  1779. * @param {object} data
  1780. * @param {object} opt
  1781. * @param {object} params
  1782. */
  1783. installVersionSuccessCallback: function (data, opt, params) {
  1784. App.HostStackVersion.find(params.version.get('id')).set('status', 'INSTALLING');
  1785. }
  1786. });