details.js 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435
  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 hostsManagement = require('utils/hosts');
  22. var stringUtils = require('utils/string_utils');
  23. App.MainHostDetailsController = Em.Controller.extend({
  24. name: 'mainHostDetailsController',
  25. /**
  26. * Viewed host
  27. * @type {App.Host|null}
  28. */
  29. content: null,
  30. /**
  31. * Does user come from hosts page
  32. * @type {bool}
  33. */
  34. isFromHosts: false,
  35. /**
  36. * Are we adding hive server2 component
  37. * @type {bool}
  38. */
  39. addHiveServer: false,
  40. /**
  41. * path to page visited before
  42. * @type {string}
  43. */
  44. referer: '',
  45. /**
  46. * Host on which Hive Metastore will be added
  47. * @type {string}
  48. */
  49. hiveMetastoreHost: '',
  50. /**
  51. * Deferred object will be resolved when Oozie configs are downloaded
  52. * @type {object}
  53. */
  54. isOozieConfigLoaded: $.Deferred(),
  55. /**
  56. * @type {bool}
  57. */
  58. isOozieServerAddable: true,
  59. /**
  60. * Open dashboard page
  61. * @method routeHome
  62. */
  63. routeHome: function () {
  64. App.router.transitionTo('main.dashboard.index');
  65. },
  66. /**
  67. * List of active (not in passive state) host components
  68. * @type {Ember.Enumerable}
  69. */
  70. serviceActiveComponents: function () {
  71. return this.get('content.hostComponents').filterProperty('service.isInPassive', false);
  72. }.property('content.hostComponents'),
  73. /**
  74. * List of active host components which aren't clients
  75. * @type {Ember.Enumerable}
  76. */
  77. serviceNonClientActiveComponents: function () {
  78. return this.get('serviceActiveComponents').filterProperty('isClient', false);
  79. }.property('serviceActiveComponents'),
  80. /**
  81. * send command to server to start selected host component
  82. * @param {object} event
  83. * @method startComponent
  84. */
  85. startComponent: function (event) {
  86. var self = this;
  87. return App.showConfirmationPopup(function () {
  88. var component = event.context;
  89. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  90. self.sendComponentCommand(component, context, App.HostComponentStatus.started);
  91. });
  92. },
  93. /**
  94. * send command to server to stop selected host component
  95. * @param {object} event
  96. * @method startComponent
  97. */
  98. stopComponent: function (event) {
  99. var self = this;
  100. if (event.context.get('componentName') == 'NAMENODE' ) {
  101. this.checkNnLastCheckpointTime(function () {
  102. return App.showConfirmationPopup(function () {
  103. var component = event.context;
  104. var context = Em.I18n.t('requestInfo.stopHostComponent') + " " + component.get('displayName');
  105. self.sendComponentCommand(component, context, App.HostComponentStatus.stopped);
  106. });
  107. });
  108. } else {
  109. return App.showConfirmationPopup(function () {
  110. var component = event.context;
  111. var context = Em.I18n.t('requestInfo.stopHostComponent') + " " + component.get('displayName');
  112. self.sendComponentCommand(component, context, App.HostComponentStatus.stopped);
  113. });
  114. }
  115. },
  116. /**
  117. * PUTs a command to server to start/stop a component. If no
  118. * specific component is provided, all components are started.
  119. * @param {object} component When <code>null</code> all startable components are started.
  120. * @param {String} context Context under which this command is beign sent.
  121. * @param {String} state - desired state of component can be 'STARTED' or 'STOPPED'
  122. * @method sendComponentCommand
  123. */
  124. sendComponentCommand: function (component, context, state) {
  125. var data = {
  126. hostName: this.get('content.hostName'),
  127. context: context,
  128. component: component,
  129. HostRoles: {
  130. state: state
  131. }
  132. };
  133. if (Array.isArray(component)) {
  134. data.query = "HostRoles/component_name.in(" + component.mapProperty('componentName').join(',') + ")";
  135. } else {
  136. data.componentName = component.get('componentName');
  137. data.serviceName = component.get('service.serviceName');
  138. }
  139. App.ajax.send({
  140. name: (Array.isArray(component)) ? 'common.host.host_components.update' : 'common.host.host_component.update',
  141. sender: this,
  142. data: data,
  143. success: 'sendComponentCommandSuccessCallback',
  144. error: 'ajaxErrorCallback'
  145. });
  146. },
  147. /**
  148. * Success callback for stop/start host component request
  149. * @param {object} data
  150. * @param {object} opt
  151. * @param {object} params
  152. * @method stopComponentSuccessCallback
  153. */
  154. sendComponentCommandSuccessCallback: function (data, opt, params) {
  155. var running = (params.HostRoles.state === App.HostComponentStatus.stopped) ? App.HostComponentStatus.stopping : App.HostComponentStatus.starting;
  156. console.log('Send request for ' + running + ' successfully');
  157. params.component.set('workStatus', running);
  158. if (App.get('testMode')) {
  159. this.mimicWorkStatusChange(params.component, running, params.HostRoles.state);
  160. }
  161. this.showBackgroundOperationsPopup();
  162. },
  163. /**
  164. * Default error-callback for ajax-requests in current page
  165. * @param {object} request
  166. * @param {object} ajaxOptions
  167. * @param {string} error
  168. * @param {object} opt
  169. * @param {object} params
  170. * @method ajaxErrorCallback
  171. */
  172. ajaxErrorCallback: function (request, ajaxOptions, error, opt, params) {
  173. return componentsUtils.ajaxErrorCallback(request, ajaxOptions, error, opt, params);
  174. },
  175. /**
  176. * this function will be called from :1) stop NN 2) restart NN 3) stop all components
  177. * @param callback - callback function to continue next operation
  178. * @param hostname - namenode host (by default is current host)
  179. */
  180. checkNnLastCheckpointTime: function(callback, hostName) {
  181. var self = this;
  182. this.pullNnCheckPointTime(hostName).complete(function () {
  183. var isNNCheckpointTooOld = self.get('isNNCheckpointTooOld');
  184. self.set('isNNCheckpointTooOld', null);
  185. if (isNNCheckpointTooOld) {
  186. // too old
  187. var msg = Em.Object.create({
  188. confirmMsg: Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld') +
  189. Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions').format(isNNCheckpointTooOld),
  190. confirmButton: Em.I18n.t('common.next')
  191. });
  192. return App.showConfirmationFeedBackPopup(callback, msg);
  193. } else if (isNNCheckpointTooOld == null) {
  194. // not available
  195. return App.showConfirmationPopup(
  196. callback, Em.I18n.t('services.service.stop.HDFS.warningMsg.checkPointNA'), null,
  197. Em.I18n.t('common.warning'), Em.I18n.t('common.proceedAnyway'), true
  198. );
  199. } else {
  200. // still young
  201. callback();
  202. }
  203. });
  204. },
  205. pullNnCheckPointTime: function (hostName) {
  206. return App.ajax.send({
  207. name: 'common.host_component.getNnCheckPointTime',
  208. sender: this,
  209. data: {
  210. host: hostName || this.get('content.hostName')
  211. },
  212. success: 'parseNnCheckPointTime'
  213. });
  214. },
  215. parseNnCheckPointTime: function (data) {
  216. var lastCheckpointTime = Em.get(data, 'metrics.dfs.FSNamesystem.LastCheckpointTime');
  217. var hostName = Em.get(data, 'HostRoles.host_name');
  218. if (Em.get(data, 'metrics.dfs.FSNamesystem.HAState') == 'active') {
  219. if (!lastCheckpointTime) {
  220. this.set("isNNCheckpointTooOld", null);
  221. } else {
  222. var time_criteria = 12; // time in hours to define how many hours ago is too old
  223. var time_ago = (Math.round(App.dateTime() / 1000) - (time_criteria * 3600)) *1000;
  224. if (lastCheckpointTime <= time_ago) {
  225. // too old, set the effected hostName
  226. this.set("isNNCheckpointTooOld", hostName);
  227. } else {
  228. // still young
  229. this.set("isNNCheckpointTooOld", false);
  230. }
  231. }
  232. } else if (Em.get(data, 'metrics.dfs.FSNamesystem.HAState') == 'standby') {
  233. this.set("isNNCheckpointTooOld", false);
  234. }
  235. },
  236. /**
  237. * mimic status transition in test mode
  238. * @param entity
  239. * @param transitionalState
  240. * @param finalState
  241. */
  242. mimicWorkStatusChange: function (entity, transitionalState, finalState) {
  243. if (Em.isArray(entity)) {
  244. entity.forEach(function (item) {
  245. item.set('workStatus', transitionalState);
  246. setTimeout(function () {
  247. item.set('workStatus', finalState);
  248. }, App.testModeDelayForActions);
  249. });
  250. } else {
  251. entity.set('workStatus', transitionalState);
  252. setTimeout(function () {
  253. entity.set('workStatus', finalState);
  254. }, App.testModeDelayForActions);
  255. }
  256. },
  257. /**
  258. * load data (if we need to show this background operations popup) from persist
  259. * @param callback
  260. */
  261. showBackgroundOperationsPopup: function (callback) {
  262. App.router.get('applicationController').dataLoading().done(function (initValue) {
  263. if (initValue) {
  264. App.router.get('backgroundOperationsController').showPopup();
  265. }
  266. if (typeof callback === 'function') {
  267. callback();
  268. }
  269. });
  270. },
  271. /**
  272. * Send command to server to delete selected host component
  273. * @param {object} event
  274. * @method deleteComponent
  275. */
  276. deleteComponent: function (event) {
  277. if ($(event.target).closest('li').hasClass('disabled')) {
  278. return;
  279. }
  280. var self = this;
  281. var component = event.context;
  282. var componentName = component.get('componentName');
  283. var displayName = component.get('displayName');
  284. var isLastComponent = (this.getTotalComponent(component) === 1);
  285. return App.ModalPopup.show({
  286. header: Em.I18n.t('popup.confirmation.commonHeader'),
  287. primary: Em.I18n.t('hosts.host.deleteComponent.popup.confirm'),
  288. bodyClass: Em.View.extend({
  289. templateName: require('templates/main/host/details/deleteComponentPopup')
  290. }),
  291. isHiveMetastore: function () {
  292. return componentName == 'HIVE_METASTORE';
  293. }.property(),
  294. deleteHiveMetastoreMsg: Em.View.extend({
  295. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteHiveMetastore'))
  296. }),
  297. isNimbus: function () {
  298. return componentName == 'NIMBUS';
  299. }.property(),
  300. deleteNimbusMsg: Em.View.extend({
  301. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteNimbus'))
  302. }),
  303. isRangerKMSServer: function () {
  304. return componentName == 'RANGER_KMS_SERVER';
  305. }.property(),
  306. deleteRangerKMSServereMsg: Em.View.extend({
  307. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteRangerKMSServer'))
  308. }),
  309. isChecked: false,
  310. disablePrimary: function () {
  311. return !this.get('isChecked');
  312. }.property('isChecked'),
  313. lastComponent: function () {
  314. this.set('isChecked', !isLastComponent);
  315. return isLastComponent;
  316. }.property(),
  317. isZkServer: function () {
  318. return componentName == 'ZOOKEEPER_SERVER';
  319. }.property(),
  320. lastComponentError: Em.View.extend({
  321. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  322. }),
  323. deleteComponentMsg: function () {
  324. return Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(displayName);
  325. }.property(),
  326. deleteZkServerMsg: Em.View.extend({
  327. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.deleteZooKeeperServer'))
  328. }),
  329. onPrimary: function () {
  330. var popup = this;
  331. self._doDeleteHostComponent(component, function () {
  332. self.set('redrawComponents', true);
  333. popup.hide();
  334. });
  335. }
  336. });
  337. },
  338. /**
  339. * get total count of host-components
  340. * @method getTotalComponent
  341. * @param component
  342. * @return {Number}
  343. */
  344. getTotalComponent: function (component) {
  345. var count;
  346. if (component.get('isSlave')) {
  347. count = App.SlaveComponent.find(component.get('componentName')).get('totalCount');
  348. } else if (component.get('isClient')) {
  349. count = App.ClientComponent.find(component.get('componentName')).get('totalCount');
  350. } else {
  351. count = App.HostComponent.find().filterProperty('componentName', component.get('componentName')).get('length');
  352. }
  353. return count || 0;
  354. },
  355. /**
  356. * Trigger to reset list of master/slaves components on the view
  357. * @type {bool}
  358. */
  359. redrawComponents: false,
  360. /**
  361. * Deletes the given host component, or all host components.
  362. *
  363. * @param {object|null} component When <code>null</code> all host components are deleted.
  364. * @return <code>null</code> when components get deleted.
  365. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  366. * when components failed to get deleted.
  367. * @method _doDeleteHostComponent
  368. */
  369. _doDeleteHostComponent: function (component, callback) {
  370. callback = callback || Em.K;
  371. App.ajax.send({
  372. name: (Em.isNone(component)) ? 'common.delete.host' : 'common.delete.host_component',
  373. sender: this,
  374. data: {
  375. componentName: (component) ? component.get('componentName') : '',
  376. hostName: this.get('content.hostName')
  377. },
  378. success: '_doDeleteHostComponentSuccessCallback',
  379. error: '_doDeleteHostComponentErrorCallback'
  380. }).then(callback, callback);
  381. },
  382. /**
  383. * Result of delete component(s) request
  384. * @type {object}
  385. */
  386. _deletedHostComponentResult: null,
  387. /**
  388. * Success callback for delete host component request
  389. * @method _doDeleteHostComponentSuccessCallback
  390. */
  391. _doDeleteHostComponentSuccessCallback: function (response, request, data) {
  392. var self = this;
  393. this.set('_deletedHostComponentResult', null);
  394. this.removeHostComponentModel(data.componentName, data.hostName);
  395. if (data.componentName == 'ZOOKEEPER_SERVER') {
  396. this.set('fromDeleteZkServer', true);
  397. this.updateStormConfigs();
  398. var callback = function () {
  399. self.loadConfigs();
  400. };
  401. self.isServiceMetricsLoaded(callback);
  402. } else if (data.componentName == 'HIVE_METASTORE') {
  403. this.set('deleteHiveMetaStore', true);
  404. this.loadConfigs('loadHiveConfigs');
  405. } else if (data.componentName == 'NIMBUS') {
  406. this.set('deleteNimbusHost', true);
  407. this.loadConfigs('loadStormConfigs');
  408. } else if (data.componentName == 'RANGER_KMS_SERVER') {
  409. this.set('deleteRangerKMSServer', true);
  410. this.loadConfigs('loadRangerConfigs');
  411. }
  412. },
  413. /**
  414. * Error-callback for delete host component request
  415. * @param {object} xhr
  416. * @param {string} textStatus
  417. * @param {object} errorThrown
  418. * @method _doDeleteHostComponentErrorCallback
  419. */
  420. _doDeleteHostComponentErrorCallback: function (xhr, textStatus, errorThrown, data) {
  421. console.log('Error deleting host component');
  422. console.log(textStatus);
  423. console.log(errorThrown);
  424. this.set('_deletedHostComponentResult', {xhr: xhr, url: data.url, method: 'DELETE'});
  425. },
  426. /**
  427. * Remove host component data from App.HostComponent model.
  428. *
  429. * @param {String} componentName
  430. * @param {String} hostName
  431. */
  432. removeHostComponentModel: function (componentName, hostName) {
  433. var component = App.HostComponent.find().filterProperty('componentName', componentName).findProperty('hostName', hostName);
  434. var serviceInCache = App.cache['services'].findProperty('ServiceInfo.service_name', component.get('service.serviceName'));
  435. serviceInCache.host_components = serviceInCache.host_components.without(component.get('id'));
  436. App.serviceMapper.deleteRecord(component);
  437. },
  438. /**
  439. * Send command to server to upgrade selected host component
  440. * @param {object} event
  441. * @method upgradeComponent
  442. */
  443. upgradeComponent: function (event) {
  444. var self = this;
  445. var component = event.context;
  446. return App.showConfirmationPopup(function () {
  447. App.ajax.send({
  448. name: 'host.host_component.upgrade',
  449. sender: self,
  450. data: {
  451. component: component,
  452. hostName: self.get('content.hostName'),
  453. componentName: component.get('componentName'),
  454. data: JSON.stringify({
  455. RequestInfo: {
  456. "context": Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  457. },
  458. Body: {
  459. HostRoles: {
  460. stack_id: 'HDP-1.2.2',
  461. state: 'INSTALLED'
  462. }
  463. }
  464. })
  465. },
  466. success: 'upgradeComponentSuccessCallback',
  467. error: 'ajaxErrorCallback'
  468. });
  469. });
  470. },
  471. /**
  472. * Success callback for upgrade host component request
  473. * @param {object} data
  474. * @param {object} opt
  475. * @param {object} params
  476. * @method upgradeComponentSuccessCallback
  477. */
  478. upgradeComponentSuccessCallback: function (data, opt, params) {
  479. console.log('Send request for UPGRADE successfully');
  480. if (App.get('testMode')) {
  481. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.starting, App.HostComponentStatus.started);
  482. }
  483. this.showBackgroundOperationsPopup();
  484. },
  485. /**
  486. * Send command to server to restart selected components
  487. * @param {object} event
  488. * @method restartComponent
  489. */
  490. restartComponent: function (event) {
  491. var component = event.context;
  492. if (event.context.get('componentName') == 'NAMENODE') {
  493. this.checkNnLastCheckpointTime(function () {
  494. return App.showConfirmationPopup(function () {
  495. batchUtils.restartHostComponents([component], Em.I18n.t('rollingrestart.context.selectedComponentOnSelectedHost').format(component.get('displayName')), "HOST_COMPONENT");
  496. });
  497. });
  498. } else {
  499. return App.showConfirmationPopup(function () {
  500. batchUtils.restartHostComponents([component], Em.I18n.t('rollingrestart.context.selectedComponentOnSelectedHost').format(component.get('displayName')), "HOST_COMPONENT");
  501. });
  502. }
  503. },
  504. /**
  505. * add component as <code>addComponent<code> method but perform
  506. * kdc sessionstate if cluster is secure;
  507. * @param event
  508. */
  509. addComponentWithCheck: function (event) {
  510. var componentName = event.context ? event.context.get('componentName') : "";
  511. event.hiveMetastoreHost = (componentName == "HIVE_METASTORE" && !!this.get('content.hostName')) ? this.get('content.hostName') : null;
  512. App.get('router.mainAdminKerberosController').getSecurityType(function (event) {
  513. App.get('router.mainAdminKerberosController').getKDCSessionState(this.addComponent.bind(this, event));
  514. }.bind(this, event));
  515. },
  516. /**
  517. * Send command to server to install selected host component
  518. * @param {object} event
  519. * @method addComponent
  520. */
  521. addComponent: function (event) {
  522. var
  523. returnFunc,
  524. self = this,
  525. component = event.context,
  526. hostName = event.selectedHost || this.get('content.hostName'),
  527. componentName = component.get('componentName'),
  528. missedComponents = event.selectedHost ? [] : componentsUtils.checkComponentDependencies(componentName, {
  529. scope: 'host',
  530. installedComponents: this.get('content.hostComponents').mapProperty('componentName')
  531. }),
  532. isManualKerberos = App.get('router.mainAdminKerberosController.isManualKerberos'),
  533. manualKerberosWarning = isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : '';
  534. if (!!missedComponents.length) {
  535. var popupMessage = Em.I18n.t('host.host.addComponent.popup.dependedComponents.body').format(component.get('displayName'),
  536. stringUtils.getFormattedStringFromArray(missedComponents.map(function (cName) {
  537. return App.StackServiceComponent.find(cName).get('displayName');
  538. })));
  539. return App.showAlertPopup(Em.I18n.t('host.host.addComponent.popup.dependedComponents.header'), popupMessage);
  540. }
  541. switch (componentName) {
  542. case 'ZOOKEEPER_SERVER':
  543. returnFunc = App.showConfirmationPopup(function () {
  544. self.primary(component);
  545. }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning);
  546. break;
  547. case 'HIVE_METASTORE':
  548. returnFunc = App.showConfirmationPopup(function () {
  549. self.set('hiveMetastoreHost', hostName);
  550. self.loadConfigs("loadHiveConfigs");
  551. }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning);
  552. break;
  553. case 'NIMBUS':
  554. returnFunc = App.showConfirmationPopup(function () {
  555. self.set('nimbusHost', hostName);
  556. self.loadConfigs("loadStormConfigs");
  557. }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning);
  558. break;
  559. case 'RANGER_KMS_SERVER':
  560. returnFunc = App.showConfirmationPopup(function () {
  561. self.set('rangerKMSServerHost', hostName);
  562. self.loadConfigs("loadRangerConfigs");
  563. }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning);
  564. break;
  565. default:
  566. returnFunc = this.addClientComponent(component, isManualKerberos);
  567. }
  568. return returnFunc;
  569. },
  570. /**
  571. * Send command to server to install client on selected host
  572. * @param component
  573. */
  574. addClientComponent: function (component, isManualKerberos) {
  575. var self = this;
  576. var message = this.formatClientsMessage(component);
  577. return this.showAddComponentPopup(message, isManualKerberos, function () {
  578. self.primary(component);
  579. });
  580. },
  581. showAddComponentPopup: function (message, isManualKerberos, primary) {
  582. isManualKerberos = isManualKerberos || false;
  583. return App.ModalPopup.show({
  584. primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'),
  585. header: Em.I18n.t('popup.confirmation.commonHeader'),
  586. addComponentMsg: function () {
  587. return Em.I18n.t('hosts.host.addComponent.msg').format(message);
  588. }.property(),
  589. manualKerberosWarning: function () {
  590. return isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : '';
  591. }.property(),
  592. bodyClass: Em.View.extend({
  593. templateName: require('templates/main/host/details/addComponentPopup')
  594. }),
  595. onPrimary: function () {
  596. this.hide();
  597. primary();
  598. }
  599. });
  600. },
  601. /**
  602. * format message for operation of adding clients
  603. * @param client
  604. */
  605. formatClientsMessage: function (client) {
  606. var displayName = Em.isNone(client.get('displayName')) ? '' : client.get('displayName');
  607. var subComponentNames = client.get('subComponentNames');
  608. if (subComponentNames && subComponentNames.length > 0) {
  609. var dns = [];
  610. subComponentNames.forEach(function (scn) {
  611. dns.push(App.format.role(scn));
  612. });
  613. displayName += " (" + dns.join(", ") + ")";
  614. }
  615. return displayName;
  616. },
  617. /**
  618. * Send request to add host component
  619. * @param {App.HostComponent} component
  620. * @method primary
  621. */
  622. primary: function (component) {
  623. var self = this;
  624. componentsUtils.installHostComponent(self.get('content.hostName'), component);
  625. },
  626. /**
  627. * Success callback for install host component request (sent in <code>addNewComponentSuccessCallback</code>)
  628. * @param {object} data
  629. * @param {object} opt
  630. * @param {object} params
  631. * @method installNewComponentSuccessCallbƒack
  632. */
  633. installNewComponentSuccessCallback: function (data, opt, params) {
  634. if (!data || !data.Requests || !data.Requests.id) {
  635. return false;
  636. }
  637. var self = this;
  638. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  639. if (App.get('testMode')) {
  640. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.installing, App.HostComponentStatus.stopped);
  641. }
  642. this.showBackgroundOperationsPopup(function () {
  643. if (params.componentName === 'ZOOKEEPER_SERVER' || params.componentName === 'HIVE_SERVER') {
  644. self.set(params.componentName === 'ZOOKEEPER_SERVER' ? 'zkRequestId' : 'hiveRequestId', data.Requests.id);
  645. self.addObserver(
  646. 'App.router.backgroundOperationsController.serviceTimestamp',
  647. self,
  648. (params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs : self.checkHiveDone)
  649. );
  650. params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs() : self.checkHiveDone();
  651. }
  652. });
  653. return true;
  654. },
  655. /**
  656. * Call <code>setRackInfo</code> function to show Set Rack Id popup
  657. * @param data
  658. */
  659. setRackId: function (data) {
  660. var rack = data.context.get('rack');
  661. var hosts = [data.context];
  662. var operationData = {message: Em.I18n.t('hosts.host.details.setRackId')};
  663. hostsManagement.setRackInfo(operationData, hosts, rack);
  664. },
  665. /**
  666. * Call load tags
  667. * @method checkHiveDone
  668. */
  669. checkHiveDone: function () {
  670. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('hiveRequestId'));
  671. if (bg && !bg.get('isRunning')) {
  672. var self = this;
  673. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkHiveDone);
  674. setTimeout(function () {
  675. self.set('addHiveServer', true);
  676. self.loadConfigs("loadHiveConfigs");
  677. }, App.get('componentsUpdateInterval'));
  678. }
  679. },
  680. /**
  681. * Success callback for load configs request
  682. * @param {object} data
  683. * @method loadOozieConfigs
  684. */
  685. loadOozieConfigs: function (data) {
  686. return App.ajax.send({
  687. name: 'admin.get.all_configurations',
  688. sender: this,
  689. data: {
  690. urlParams: '(type=oozie-env&tag=' + data.Clusters.desired_configs['oozie-env'].tag + ')'
  691. },
  692. success: 'onLoadOozieConfigs',
  693. error: 'onLoadConfigsErrorCallback'
  694. });
  695. },
  696. /**
  697. * get Oozie database config and set databaseType
  698. * @param {object} data
  699. * @method onLoadHiveConfigs
  700. */
  701. onLoadOozieConfigs: function (data) {
  702. var configs = {};
  703. data.items.forEach(function (item) {
  704. $.extend(configs, item.properties);
  705. });
  706. this.set('isOozieServerAddable', !(Em.isEmpty(configs["oozie_database"]) || configs["oozie_database"] === 'New Derby Database'));
  707. this.get('isOozieConfigLoaded').resolve();
  708. },
  709. /**
  710. * Success callback for Storm load configs request
  711. * @param {object} data
  712. * @method loadStormConfigs
  713. */
  714. loadStormConfigs: function (data) {
  715. App.ajax.send({
  716. name: 'admin.get.all_configurations',
  717. sender: this,
  718. data: {
  719. urlParams: '(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')'
  720. },
  721. success: 'onLoadStormConfigs'
  722. });
  723. },
  724. /**
  725. * Update zk configs
  726. * @param {object} configs
  727. * @method updateZkConfigs
  728. */
  729. updateZkConfigs: function (configs) {
  730. var zks = this.getZkServerHosts();
  731. var portValue = configs['zoo.cfg'] && Em.get(configs['zoo.cfg'], 'clientPort');
  732. var zkPort = typeof portValue === 'udefined' ? '2181' : portValue;
  733. var zksWithPort = this.concatZkNames(zks, zkPort);
  734. this.setZKConfigs(configs, zksWithPort, zks);
  735. },
  736. /**
  737. * update and save Storm related configs to server
  738. * @param {object} data
  739. * @method onLoadStormConfigs
  740. */
  741. onLoadStormConfigs: function (data) {
  742. var nimbusHost = this.get('nimbusHost'),
  743. stormNimbusHosts = this.getStormNimbusHosts(),
  744. configs = {},
  745. attributes = {};
  746. data.items.forEach(function (item) {
  747. configs[item.type] = item.properties;
  748. attributes[item.type] = item.properties_attributes || {};
  749. }, this);
  750. this.updateZkConfigs(configs);
  751. configs['storm-site']['nimbus.seeds'] = JSON.stringify(stormNimbusHosts).replace(/"/g, "'");
  752. var groups = [
  753. {
  754. properties: {
  755. 'storm-site': configs['storm-site']
  756. },
  757. properties_attributes: {
  758. 'storm-site': attributes['storm-site']
  759. }
  760. }
  761. ];
  762. this.saveConfigsBatch(groups, 'NIMBUS', nimbusHost);
  763. },
  764. /**
  765. * Success callback for load configs request
  766. * @param {object} data
  767. * @method loadHiveConfigs
  768. */
  769. loadHiveConfigs: function (data) {
  770. App.ajax.send({
  771. name: 'admin.get.all_configurations',
  772. sender: this,
  773. data: {
  774. urlParams: '(type=hive-site&tag=' + data.Clusters.desired_configs['hive-site'].tag + ')|(type=webhcat-site&tag=' +
  775. data.Clusters.desired_configs['webhcat-site'].tag + ')|(type=hive-env&tag=' + data.Clusters.desired_configs['hive-env'].tag +
  776. ')|(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')'
  777. },
  778. success: 'onLoadHiveConfigs'
  779. });
  780. },
  781. /**
  782. * update and save Hive related configs to server
  783. * @param {object} data
  784. * @method onLoadHiveConfigs
  785. */
  786. onLoadHiveConfigs: function (data) {
  787. var
  788. hiveMetastoreHost = this.get('hiveMetastoreHost'),
  789. hiveMSHosts = this.getHiveHosts(),
  790. hiveMasterHosts = hiveMSHosts.concat(App.HostComponent.find().filterProperty('componentName', 'HIVE_SERVER').mapProperty('hostName')).uniq().sort().join(','),
  791. configs = {},
  792. attributes = {},
  793. port = "",
  794. hiveUser = "",
  795. webhcatUser = "";
  796. data.items.forEach(function (item) {
  797. configs[item.type] = item.properties;
  798. attributes[item.type] = item.properties_attributes || {};
  799. }, this);
  800. port = configs['hive-site']['hive.metastore.uris'].match(/:[0-9]{2,4}/);
  801. port = port ? port[0].slice(1) : "9083";
  802. hiveUser = configs['hive-env']['hive_user'];
  803. webhcatUser = configs['hive-env']['webhcat_user'];
  804. for (var i = 0; i < hiveMSHosts.length; i++) {
  805. hiveMSHosts[i] = "thrift://" + hiveMSHosts[i] + ":" + port;
  806. }
  807. configs['hive-site']['hive.metastore.uris'] = hiveMSHosts.join(',');
  808. configs['webhcat-site']['templeton.hive.properties'] = configs['webhcat-site']['templeton.hive.properties'].replace(/thrift.+[0-9]{2,},/i, hiveMSHosts.join('\\,') + ",");
  809. configs['core-site']['hadoop.proxyuser.' + hiveUser + '.hosts'] = hiveMasterHosts;
  810. configs['core-site']['hadoop.proxyuser.' + webhcatUser + '.hosts'] = hiveMasterHosts;
  811. var groups = [
  812. {
  813. properties: {
  814. 'hive-site': configs['hive-site'],
  815. 'webhcat-site': configs['webhcat-site'],
  816. 'hive-env': configs['hive-env']
  817. },
  818. properties_attributes: {
  819. 'hive-site': attributes['hive-site'],
  820. 'webhcat-site': attributes['webhcat-site'],
  821. 'hive-env': attributes['hive-env']
  822. }
  823. },
  824. {
  825. properties: {
  826. 'core-site': configs['core-site']
  827. },
  828. properties_attributes: {
  829. 'core-site': attributes['core-site']
  830. }
  831. }
  832. ];
  833. this.saveConfigsBatch(groups, this.get('addHiveServer') ? 'HIVE_SERVER' : 'HIVE_METASTORE', hiveMetastoreHost);
  834. this.set('addHiveServer', false);
  835. },
  836. /**
  837. * save configs' sites in batch
  838. * @param groups
  839. * @param componentName
  840. * @param host
  841. */
  842. saveConfigsBatch: function (groups, componentName, host) {
  843. groups.forEach(function (group) {
  844. var desiredConfigs = [],
  845. tag = 'version' + (new Date).getTime(),
  846. properties = group.properties;
  847. for (var site in properties) {
  848. if (!properties.hasOwnProperty(site) || Em.isNone(properties[site])) continue;
  849. desiredConfigs.push({
  850. "type": site,
  851. "tag": tag,
  852. "properties": properties[site],
  853. "properties_attributes": group.properties_attributes[site],
  854. "service_config_version_note": Em.I18n.t('hosts.host.configs.save.note').format(App.format.role(componentName))
  855. });
  856. }
  857. if (desiredConfigs.length > 0) {
  858. App.ajax.send({
  859. name: 'common.service.configurations',
  860. sender: this,
  861. data: {
  862. desired_config: desiredConfigs,
  863. componentName: componentName,
  864. host: host
  865. },
  866. success: 'installHostComponent'
  867. });
  868. }
  869. //clear hive metastore host not to send second request to install component
  870. host = null;
  871. }, this);
  872. },
  873. /**
  874. * success callback for saveConfigsBatch method
  875. * @param data
  876. * @param opt
  877. * @param params
  878. */
  879. installHostComponent: function (data, opt, params) {
  880. if (params.host) {
  881. componentsUtils.installHostComponent(params.host, App.StackServiceComponent.find(params.componentName));
  882. }
  883. },
  884. /**
  885. * Delete Hive Metastore is performed
  886. * @type {bool}
  887. */
  888. deleteHiveMetaStore: false,
  889. getHiveHosts: function () {
  890. var
  891. hiveHosts = App.HostComponent.find().filterProperty('componentName', 'HIVE_METASTORE').mapProperty('hostName'),
  892. hiveMetastoreHost = this.get('hiveMetastoreHost');
  893. if (!!hiveMetastoreHost) {
  894. hiveHosts.push(hiveMetastoreHost);
  895. this.set('hiveMetastoreHost', '');
  896. }
  897. if (this.get('fromDeleteHost') || this.get('deleteHiveMetaStore')) {
  898. this.set('deleteHiveMetaStore', false);
  899. this.set('fromDeleteHost', false);
  900. return hiveHosts.without(this.get('content.hostName'));
  901. }
  902. return hiveHosts.sort();
  903. },
  904. /**
  905. * Success callback for load configs request
  906. * @param {object} data
  907. * @method loadHiveConfigs
  908. */
  909. loadRangerConfigs: function (data) {
  910. App.ajax.send({
  911. name: 'admin.get.all_configurations',
  912. sender: this,
  913. data: {
  914. urlParams: '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')|(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')|(type=kms-env&tag=' + data.Clusters.desired_configs['kms-env'].tag + ')'
  915. },
  916. success: 'onLoadRangerConfigs'
  917. });
  918. },
  919. /**
  920. * update and save Hive hive.metastore.uris config to server
  921. * @param {object} data
  922. * @method onLoadHiveConfigs
  923. */
  924. onLoadRangerConfigs: function (data) {
  925. var hostToInstall = this.get('rangerKMSServerHost');
  926. var rkmsHosts = this.getRangerKMSServerHosts();
  927. var rkmsPort = data.items.findProperty('type', 'kms-env').properties['kms_port'];
  928. var coreSiteConfigs = data.items.findProperty('type', 'core-site');
  929. var hdfsSiteConfigs = data.items.findProperty('type', 'hdfs-site');
  930. var groups = [
  931. {
  932. properties: {
  933. 'core-site': coreSiteConfigs.properties,
  934. 'hdfs-site': hdfsSiteConfigs.properties
  935. },
  936. properties_attributes: {
  937. 'core-site': coreSiteConfigs.properties_attributes,
  938. 'hdfs-site': hdfsSiteConfigs.properties_attributes
  939. }
  940. }
  941. ];
  942. coreSiteConfigs.properties['hadoop.security.key.provider.path'] = 'kms://http@' + rkmsHosts.join(';') + ':' + rkmsPort + '/kms';
  943. hdfsSiteConfigs.properties['dfs.encryption.key.provider.uri'] = 'kms://http@' + rkmsHosts.join(';') + ':' + rkmsPort + '/kms';
  944. this.saveConfigsBatch(groups, 'RANGER_KMS_SERVER', hostToInstall);
  945. },
  946. /**
  947. * Delete Hive Metastore is performed
  948. * @type {bool}
  949. */
  950. deleteRangerKMSServer: false,
  951. getRangerKMSServerHosts: function () {
  952. var rkmsHosts = App.HostComponent.find().filterProperty('componentName', 'RANGER_KMS_SERVER').mapProperty('hostName');
  953. var rangerKMSServerHost = this.get('rangerKMSServerHost');
  954. if (!!rangerKMSServerHost) {
  955. rkmsHosts.push(rangerKMSServerHost);
  956. this.set('rangerKMSServerHost', '');
  957. }
  958. if (this.get('fromDeleteHost') || this.get('deleteRangerKMSServer')) {
  959. this.set('deleteRangerKMSServer', false);
  960. this.set('fromDeleteHost', false);
  961. return rkmsHosts.without(this.get('content.hostName'));
  962. }
  963. return rkmsHosts.sort();
  964. },
  965. /**
  966. * Delete Storm Nimbus is performed
  967. * @type {bool}
  968. */
  969. deleteNimbusHost: false,
  970. getStormNimbusHosts: function () {
  971. var
  972. stormNimbusHosts = App.HostComponent.find().filterProperty('componentName', 'NIMBUS').mapProperty('hostName'),
  973. nimbusHost = this.get('nimbusHost');
  974. if (!!nimbusHost) {
  975. stormNimbusHosts.push(nimbusHost);
  976. this.set('nimbusHost', '');
  977. }
  978. if (this.get('fromDeleteHost') || this.get('deleteNimbusHost')) {
  979. this.set('deleteNimbusHost', false);
  980. this.set('fromDeleteHost', false);
  981. return stormNimbusHosts.without(this.get('content.hostName'));
  982. }
  983. return stormNimbusHosts.sort();
  984. },
  985. /**
  986. * Send command to server to resfresh configs of selected component
  987. * @param {object} event
  988. * @method refreshComponentConfigs
  989. */
  990. refreshComponentConfigs: function (event) {
  991. var self = this;
  992. return App.showConfirmationPopup(function () {
  993. var component = event.context;
  994. var context = Em.I18n.t('requestInfo.refreshComponentConfigs').format(component.get('displayName'));
  995. self.sendRefreshComponentConfigsCommand(component, context);
  996. });
  997. },
  998. /**
  999. * PUTs a command to server to refresh configs of host component.
  1000. * @param {object} component
  1001. * @param {object} context Context under which this command is beign sent.
  1002. * @method sendRefreshComponentConfigsCommand
  1003. */
  1004. sendRefreshComponentConfigsCommand: function (component, context) {
  1005. var resource_filters = [
  1006. {
  1007. service_name: component.get('service.serviceName'),
  1008. component_name: component.get('componentName'),
  1009. hosts: component.get('host.hostName')
  1010. }
  1011. ];
  1012. App.ajax.send({
  1013. name: 'host.host_component.refresh_configs',
  1014. sender: this,
  1015. data: {
  1016. resource_filters: resource_filters,
  1017. context: context
  1018. },
  1019. success: 'refreshComponentConfigsSuccessCallback'
  1020. });
  1021. },
  1022. /**
  1023. * Success callback for refresh host component configs request
  1024. * @method refreshComponentConfigsSuccessCallback
  1025. */
  1026. refreshComponentConfigsSuccessCallback: function () {
  1027. console.log('Send request for refresh configs successfully');
  1028. this.showBackgroundOperationsPopup();
  1029. },
  1030. /**
  1031. * Update storm config
  1032. * @method updateStormConfigs
  1033. */
  1034. updateStormConfigs: function () {
  1035. if (App.Service.find('STORM').get('isLoaded') && App.get('isHadoop23Stack')) {
  1036. this.loadConfigs("loadStormConfigs");
  1037. }
  1038. },
  1039. /**
  1040. * Load tags
  1041. * @method checkZkConfigs
  1042. */
  1043. checkZkConfigs: function () {
  1044. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId'));
  1045. if (bg && !bg.get('isRunning')) {
  1046. var self = this;
  1047. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs);
  1048. setTimeout(function () {
  1049. self.updateStormConfigs();
  1050. var callback = function () {
  1051. self.loadConfigs();
  1052. };
  1053. self.isServiceMetricsLoaded(callback);
  1054. }, App.get('componentsUpdateInterval'));
  1055. }
  1056. },
  1057. /**
  1058. * Load configs
  1059. * This function when used without a callback should be always used from successcallback function of the promise `App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(promise)`
  1060. * This is required to make sure that service metrics API determining the HA state of components is loaded
  1061. * @method loadConfigs
  1062. */
  1063. loadConfigs: function (callback) {
  1064. App.ajax.send({
  1065. name: 'config.tags',
  1066. sender: this,
  1067. success: callback ? callback : 'loadConfigsSuccessCallback',
  1068. error: 'onLoadConfigsErrorCallback'
  1069. });
  1070. },
  1071. /**
  1072. * onLoadConfigsErrorCallback
  1073. * @method onLoadConfigsErrorCallback
  1074. */
  1075. onLoadConfigsErrorCallback: function () {
  1076. this.get('isOozieConfigLoaded').reject();
  1077. },
  1078. /**
  1079. * Success callback for load configs request
  1080. * @param {object} data
  1081. * @method adConfigsSuccessCallback
  1082. */
  1083. loadConfigsSuccessCallback: function (data) {
  1084. var urlParams = this.constructConfigUrlParams(data);
  1085. if (urlParams.length > 0) {
  1086. App.ajax.send({
  1087. name: 'reassign.load_configs',
  1088. sender: this,
  1089. data: {
  1090. urlParams: urlParams.join('|')
  1091. },
  1092. success: 'saveZkConfigs'
  1093. });
  1094. return true;
  1095. }
  1096. return false;
  1097. },
  1098. /**
  1099. * construct URL params for query, that load configs
  1100. * @param data {Object}
  1101. * @return {Array}
  1102. */
  1103. constructConfigUrlParams: function (data) {
  1104. var urlParams = [];
  1105. var services = App.Service.find();
  1106. if (App.get('isHaEnabled')) {
  1107. urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
  1108. }
  1109. if (services.someProperty('serviceName', 'HBASE')) {
  1110. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  1111. }
  1112. if (services.someProperty('serviceName', 'HIVE')) {
  1113. urlParams.push('(type=webhcat-site&tag=' + data.Clusters.desired_configs['webhcat-site'].tag + ')');
  1114. urlParams.push('(type=hive-site&tag=' + data.Clusters.desired_configs['hive-site'].tag + ')');
  1115. }
  1116. if (services.someProperty('serviceName', 'STORM')) {
  1117. urlParams.push('(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')');
  1118. }
  1119. if ((services.someProperty('serviceName', 'YARN') && App.get('isHadoop22Stack')) || App.get('isRMHaEnabled')) {
  1120. urlParams.push('(type=yarn-site&tag=' + data.Clusters.desired_configs['yarn-site'].tag + ')');
  1121. urlParams.push('(type=zoo.cfg&tag=' + data.Clusters.desired_configs['zoo.cfg'].tag + ')');
  1122. }
  1123. return urlParams;
  1124. },
  1125. /**
  1126. * save new ZooKeeper configs to server
  1127. * @param {object} data
  1128. * @method saveZkConfigs
  1129. */
  1130. saveZkConfigs: function (data) {
  1131. var configs = {};
  1132. var attributes = {};
  1133. data.items.forEach(function (item) {
  1134. configs[item.type] = item.properties;
  1135. attributes[item.type] = item.properties_attributes || {};
  1136. }, this);
  1137. this.updateZkConfigs(configs);
  1138. var groups = [
  1139. {
  1140. properties: {
  1141. 'hive-site': configs['hive-site'],
  1142. 'webhcat-site': configs['webhcat-site']
  1143. },
  1144. properties_attributes: {
  1145. 'hive-site': attributes['hive-site'],
  1146. 'webhcat-site': attributes['webhcat-site']
  1147. }
  1148. }
  1149. ];
  1150. if ((App.Service.find().someProperty('serviceName', 'YARN') && App.get('isHadoop22Stack')) || App.get('isRMHaEnabled')) {
  1151. groups.push(
  1152. {
  1153. properties: {
  1154. 'yarn-site': configs['yarn-site']
  1155. },
  1156. properties_attributes: {
  1157. 'yarn-site': attributes['yarn-site']
  1158. }
  1159. }
  1160. );
  1161. }
  1162. this.saveConfigsBatch(groups, 'ZOOKEEPER_SERVER');
  1163. },
  1164. /**
  1165. *
  1166. * Set new values for some configs (based on available ZooKeeper Servers)
  1167. * @param configs {object}
  1168. * @param zksWithPort {string}
  1169. * @param zks {array}
  1170. * @return {Boolean}
  1171. */
  1172. setZKConfigs: function (configs, zksWithPort, zks) {
  1173. if (typeof configs !== 'object' || !Array.isArray(zks)) return false;
  1174. if (App.get('isHaEnabled')) {
  1175. App.config.updateHostsListValue(configs['core-site'], 'ha.zookeeper.quorum', zksWithPort);
  1176. }
  1177. if (configs['hbase-site']) {
  1178. App.config.updateHostsListValue(configs['hbase-site'], 'hbase.zookeeper.quorum', zks.join(','));
  1179. }
  1180. if (configs['accumulo-site']) {
  1181. App.config.updateHostsListValue(configs['accumulo-site'], 'instance.zookeeper.host', zksWithPort);
  1182. }
  1183. if (configs['webhcat-site']) {
  1184. App.config.updateHostsListValue(configs['webhcat-site'], 'templeton.zookeeper.hosts', zksWithPort);
  1185. }
  1186. if (configs['hive-site']) {
  1187. App.config.updateHostsListValue(configs['hive-site'], 'hive.cluster.delegation.token.store.zookeeper.connectString', zksWithPort);
  1188. }
  1189. if (configs['storm-site']) {
  1190. configs['storm-site']['storm.zookeeper.servers'] = JSON.stringify(zks).replace(/"/g, "'");
  1191. }
  1192. if (App.get('isRMHaEnabled')) {
  1193. App.config.updateHostsListValue(configs['yarn-site'], 'yarn.resourcemanager.zk-address', zksWithPort);
  1194. }
  1195. if (App.get('isHadoop22Stack')) {
  1196. if (configs['hive-site']) {
  1197. App.config.updateHostsListValue(configs['hive-site'], 'hive.zookeeper.quorum', zksWithPort);
  1198. }
  1199. if (configs['yarn-site']) {
  1200. App.config.updateHostsListValue(configs['yarn-site'], 'hadoop.registry.zk.quorum', zksWithPort);
  1201. App.config.updateHostsListValue(configs['yarn-site'], 'yarn.resourcemanager.zk-address', zksWithPort);
  1202. }
  1203. }
  1204. return true;
  1205. },
  1206. /**
  1207. * concatenate URLs to ZOOKEEPER hosts with port "2181",
  1208. * as value of config divided by comma
  1209. * @param zks {array}
  1210. * @param port {string}
  1211. */
  1212. concatZkNames: function (zks, port) {
  1213. var zks_with_port = '';
  1214. zks.forEach(function (zk) {
  1215. zks_with_port += zk + ':' + port + ',';
  1216. });
  1217. return zks_with_port.slice(0, -1);
  1218. },
  1219. /**
  1220. * Is deleteHost action id fired
  1221. * @type {bool}
  1222. */
  1223. fromDeleteHost: false,
  1224. /**
  1225. * Is ZooKeeper Server being deleted from host
  1226. * @type {bool}
  1227. */
  1228. fromDeleteZkServer: false,
  1229. /**
  1230. * Get list of hostnames where ZK Server is installed
  1231. * @returns {string[]}
  1232. * @method getZkServerHosts
  1233. */
  1234. getZkServerHosts: function () {
  1235. var zks = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('hostName');
  1236. if (this.get('fromDeleteHost') || this.get('fromDeleteZkServer')) {
  1237. this.set('fromDeleteHost', false);
  1238. this.set('fromDeleteZkServer', false);
  1239. return zks.without(this.get('content.hostName'));
  1240. }
  1241. return zks;
  1242. },
  1243. /**
  1244. * Send command to server to install selected host component
  1245. * @param {Object} event
  1246. * @method installComponent
  1247. */
  1248. installComponent: function (event) {
  1249. var self = this;
  1250. var component = event.context;
  1251. var componentName = component.get('componentName');
  1252. var displayName = component.get('displayName');
  1253. return App.ModalPopup.show({
  1254. primary: Em.I18n.t('hosts.host.installComponent.popup.confirm'),
  1255. header: Em.I18n.t('popup.confirmation.commonHeader'),
  1256. installComponentMessage: function () {
  1257. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  1258. }.property(),
  1259. bodyClass: Em.View.extend({
  1260. templateName: require('templates/main/host/details/installComponentPopup')
  1261. }),
  1262. onPrimary: function () {
  1263. this.hide();
  1264. App.ajax.send({
  1265. name: 'common.host.host_component.update',
  1266. sender: self,
  1267. data: {
  1268. hostName: self.get('content.hostName'),
  1269. serviceName: component.get('service.serviceName'),
  1270. componentName: componentName,
  1271. component: component,
  1272. context: Em.I18n.t('requestInfo.installHostComponent') + " " + displayName,
  1273. HostRoles: {
  1274. state: 'INSTALLED'
  1275. }
  1276. },
  1277. success: 'installComponentSuccessCallback',
  1278. error: 'ajaxErrorCallback'
  1279. });
  1280. }
  1281. });
  1282. },
  1283. /**
  1284. * Success callback for install component request
  1285. * @param {object} data
  1286. * @param {object} opt
  1287. * @param {object} params
  1288. * @method installComponentSuccessCallback
  1289. */
  1290. installComponentSuccessCallback: function (data, opt, params) {
  1291. console.log('Send request for REINSTALL COMPONENT successfully');
  1292. if (App.get('testMode')) {
  1293. this.mimicWorkStatusChange(params.component, App.HostComponentStatus.installing, App.HostComponentStatus.stopped);
  1294. }
  1295. this.showBackgroundOperationsPopup();
  1296. },
  1297. /**
  1298. * Send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
  1299. * @param {App.HostComponent} component
  1300. * @method decommission
  1301. */
  1302. decommission: function (component) {
  1303. var self = this;
  1304. return App.showConfirmationPopup(function () {
  1305. self.runDecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
  1306. });
  1307. },
  1308. /**
  1309. * identify correct component to run decommission on them by service name,
  1310. * in result run proper decommission method
  1311. * @param hostName
  1312. * @param svcName
  1313. */
  1314. runDecommission: function (hostName, svcName) {
  1315. switch (svcName) {
  1316. case 'HDFS':
  1317. this.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
  1318. break;
  1319. case 'YARN':
  1320. this.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  1321. break;
  1322. case 'HBASE':
  1323. this.warnBeforeDecommission(hostName);
  1324. }
  1325. },
  1326. /**
  1327. * Send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
  1328. * @param {App.HostComponent} component
  1329. * @method recommission
  1330. */
  1331. recommission: function (component) {
  1332. var self = this;
  1333. return App.showConfirmationPopup(function () {
  1334. self.runRecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
  1335. });
  1336. },
  1337. /**
  1338. * identify correct component to run recommission on them by service name,
  1339. * in result run proper recommission method
  1340. * @param hostName
  1341. * @param svcName
  1342. */
  1343. runRecommission: function (hostName, svcName) {
  1344. switch (svcName) {
  1345. case 'HDFS':
  1346. this.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE");
  1347. break;
  1348. case 'YARN':
  1349. this.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  1350. break;
  1351. case 'HBASE':
  1352. this.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  1353. }
  1354. this.showBackgroundOperationsPopup();
  1355. },
  1356. /**
  1357. * Performs Decommission (for DN, TT and NM)
  1358. * @param {string} hostName
  1359. * @param {string} serviceName
  1360. * @param {string} componentName
  1361. * @param {string} slaveType
  1362. * @method doDecommission
  1363. */
  1364. doDecommission: function (hostName, serviceName, componentName, slaveType) {
  1365. var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
  1366. var context = Em.I18n.t(contextNameString);
  1367. App.ajax.send({
  1368. name: 'host.host_component.decommission_slave',
  1369. sender: this,
  1370. data: {
  1371. context: context,
  1372. command: 'DECOMMISSION',
  1373. hostName: hostName,
  1374. serviceName: serviceName,
  1375. componentName: componentName,
  1376. slaveType: slaveType
  1377. },
  1378. success: 'decommissionSuccessCallback',
  1379. error: 'decommissionErrorCallback'
  1380. });
  1381. },
  1382. /**
  1383. * check is hbase regionserver in mm. If so - run decommission
  1384. * otherwise shows warning
  1385. * @method warnBeforeDecommission
  1386. * @param {string} hostNames - list of host when run from bulk operations or current host
  1387. */
  1388. warnBeforeDecommission: function (hostNames) {
  1389. if (this.get('content.hostComponents').findProperty('componentName', 'HBASE_REGIONSERVER').get('passiveState') == "OFF") {
  1390. this.showHbaseActiveWarning();
  1391. } else {
  1392. this.checkRegionServerState(hostNames);
  1393. }
  1394. },
  1395. /**
  1396. * send call to check is this regionserver last in cluster which has desired_admin_state property "INSERVICE"
  1397. * @method checkRegionServerState
  1398. * @param hostNames
  1399. */
  1400. checkRegionServerState: function (hostNames) {
  1401. return App.ajax.send({
  1402. name: 'host.region_servers.in_inservice',
  1403. sender: this,
  1404. data: {
  1405. hostNames: hostNames
  1406. },
  1407. success: 'checkRegionServerStateSuccessCallback'
  1408. });
  1409. },
  1410. /**
  1411. * check is this regionserver last in cluster which has desired_admin_state property "INSERVICE"
  1412. * @method checkRegionServerStateSuccessCallback
  1413. * @param data
  1414. * @param opt
  1415. * @param params
  1416. */
  1417. checkRegionServerStateSuccessCallback: function (data, opt, params) {
  1418. var hostArray = params.hostNames.split(",");
  1419. var decommissionPossible = (data.items.mapProperty('HostRoles.host_name').filter(function (hostName) {
  1420. return !hostArray.contains(hostName);
  1421. }, this).length >= 1);
  1422. if (decommissionPossible) {
  1423. this.doDecommissionRegionServer(params.hostNames, "HBASE", "HBASE_MASTER", "HBASE_REGIONSERVER");
  1424. } else {
  1425. this.showRegionServerWarning();
  1426. }
  1427. },
  1428. /**
  1429. * show warning that regionserver is last in cluster which has desired_admin_state property "INSERVICE"
  1430. * @method showRegionServerWarning
  1431. * @param hostNames
  1432. */
  1433. showRegionServerWarning: function () {
  1434. return App.ModalPopup.show({
  1435. header: Em.I18n.t('common.warning'),
  1436. message: Em.I18n.t('hosts.host.hbase_regionserver.decommission.warning'),
  1437. bodyClass: Ember.View.extend({
  1438. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  1439. }),
  1440. secondary: false
  1441. });
  1442. },
  1443. /**
  1444. * shows warning: put hbase regionserver in passive state
  1445. * @method showHbaseActiveWarning
  1446. * @return {App.ModalPopup}
  1447. */
  1448. showHbaseActiveWarning: function () {
  1449. return App.ModalPopup.show({
  1450. header: Em.I18n.t('common.warning'),
  1451. message: function () {
  1452. return Em.I18n.t('hostPopup.recommendation.beforeDecommission').format(App.format.components["HBASE_REGIONSERVER"]);
  1453. }.property(),
  1454. bodyClass: Ember.View.extend({
  1455. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  1456. }),
  1457. secondary: false
  1458. });
  1459. },
  1460. /**
  1461. * Performs Decommission (for RegionServer)
  1462. * @method doDecommissionRegionServer
  1463. * @param {string} hostNames - list of host when run from bulk operations or current host
  1464. * @param {string} serviceName - serviceName
  1465. * @param {string} componentName - master compoent name
  1466. * @param {string} slaveType - slave component name
  1467. */
  1468. doDecommissionRegionServer: function (hostNames, serviceName, componentName, slaveType) {
  1469. var batches = [
  1470. {
  1471. "order_id": 1,
  1472. "type": "POST",
  1473. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/requests",
  1474. "RequestBodyInfo": {
  1475. "RequestInfo": {
  1476. "context": Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  1477. "command": "DECOMMISSION",
  1478. "exclusive": "true",
  1479. "parameters": {
  1480. "slave_type": slaveType,
  1481. "excluded_hosts": hostNames
  1482. },
  1483. 'operation_level': {
  1484. level: "HOST_COMPONENT",
  1485. cluster_name: App.get('clusterName'),
  1486. host_name: hostNames,
  1487. service_name: serviceName
  1488. }
  1489. },
  1490. "Requests/resource_filters": [
  1491. {"service_name": serviceName, "component_name": componentName}
  1492. ]
  1493. }
  1494. }];
  1495. var id = 2;
  1496. var hAray = hostNames.split(",");
  1497. for (var i = 0; i < hAray.length; i++) {
  1498. batches.push({
  1499. "order_id": id,
  1500. "type": "PUT",
  1501. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hAray[i] + "/host_components/" + slaveType,
  1502. "RequestBodyInfo": {
  1503. "RequestInfo": {
  1504. context: Em.I18n.t('hosts.host.regionserver.decommission.batch2'),
  1505. exclusive: true,
  1506. operation_level: {
  1507. level: "HOST_COMPONENT",
  1508. cluster_name: App.get('clusterName'),
  1509. host_name: hostNames,
  1510. service_name: serviceName || null
  1511. }
  1512. },
  1513. "Body": {
  1514. HostRoles: {
  1515. state: "INSTALLED"
  1516. }
  1517. }
  1518. }
  1519. });
  1520. id++;
  1521. }
  1522. batches.push({
  1523. "order_id": id,
  1524. "type": "POST",
  1525. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/requests",
  1526. "RequestBodyInfo": {
  1527. "RequestInfo": {
  1528. "context": Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  1529. "command": "DECOMMISSION",
  1530. "service_name": serviceName,
  1531. "component_name": componentName,
  1532. "parameters": {
  1533. "slave_type": slaveType,
  1534. "excluded_hosts": hostNames,
  1535. "mark_draining_only": true
  1536. },
  1537. 'operation_level': {
  1538. level: "HOST_COMPONENT",
  1539. cluster_name: App.get('clusterName'),
  1540. host_name: hostNames,
  1541. service_name: serviceName
  1542. }
  1543. },
  1544. "Requests/resource_filters": [
  1545. {"service_name": serviceName, "component_name": componentName}
  1546. ]
  1547. }
  1548. });
  1549. App.ajax.send({
  1550. name: 'host.host_component.recommission_and_restart',
  1551. sender: this,
  1552. data: {
  1553. intervalTimeSeconds: 1,
  1554. tolerateSize: 0,
  1555. batches: batches
  1556. },
  1557. success: 'decommissionSuccessCallback',
  1558. error: 'decommissionErrorCallback'
  1559. });
  1560. },
  1561. /**
  1562. * Error callback for decommission requests
  1563. * @param {object} request
  1564. * @param {object} ajaxOptions
  1565. * @param {string} error
  1566. * @method decommissionErrorCallback
  1567. */
  1568. decommissionErrorCallback: function (request, ajaxOptions, error) {
  1569. console.log('ERROR: ' + error);
  1570. },
  1571. /**
  1572. * Success ajax response for Recommission/Decommission slaves
  1573. * @param {object} data
  1574. * @method decommissionSuccessCallback
  1575. * @return {Boolean}
  1576. */
  1577. decommissionSuccessCallback: function (data) {
  1578. if (data && (data.Requests || data.resources[0].RequestSchedule)) {
  1579. this.showBackgroundOperationsPopup();
  1580. return true;
  1581. } else {
  1582. console.log('cannot get request id from ', data);
  1583. return false;
  1584. }
  1585. },
  1586. /**
  1587. * Performs Recommission and Start
  1588. * @param {string} hostNames
  1589. * @param {string} serviceName
  1590. * @param {string} componentName
  1591. * @param {string} slaveType
  1592. * @method doRecommissionAndStart
  1593. */
  1594. doRecommissionAndStart: function (hostNames, serviceName, componentName, slaveType) {
  1595. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  1596. var context_1 = Em.I18n.t(contextNameString_1);
  1597. var contextNameString_2 = 'requestInfo.startHostComponent.' + slaveType.toLowerCase();
  1598. var startContext = Em.I18n.t(contextNameString_2);
  1599. var params = {
  1600. "slave_type": slaveType,
  1601. "included_hosts": hostNames
  1602. };
  1603. if (serviceName == "HBASE") {
  1604. params.mark_draining_only = true;
  1605. }
  1606. var batches = [
  1607. {
  1608. "order_id": 1,
  1609. "type": "POST",
  1610. "uri": App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1611. "RequestBodyInfo": {
  1612. "RequestInfo": {
  1613. "context": context_1,
  1614. "command": "DECOMMISSION",
  1615. "exclusive": "true",
  1616. "parameters": params,
  1617. 'operation_level': {
  1618. level: "HOST_COMPONENT",
  1619. cluster_name: App.get('clusterName'),
  1620. host_name: hostNames,
  1621. service_name: serviceName
  1622. }
  1623. },
  1624. "Requests/resource_filters": [
  1625. {"service_name": serviceName, "component_name": componentName}
  1626. ]
  1627. }
  1628. }];
  1629. var id = 2;
  1630. var hAray = hostNames.split(",");
  1631. for (var i = 0; i < hAray.length; i++) {
  1632. batches.push({
  1633. "order_id": id,
  1634. "type": "PUT",
  1635. "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hAray[i] + "/host_components/" + slaveType,
  1636. "RequestBodyInfo": {
  1637. "RequestInfo": {
  1638. context: startContext,
  1639. operation_level: {
  1640. level: "HOST_COMPONENT",
  1641. cluster_name: App.get('clusterName'),
  1642. host_name: hostNames,
  1643. service_name: serviceName || null
  1644. }
  1645. },
  1646. "Body": {
  1647. HostRoles: {
  1648. state: "STARTED"
  1649. }
  1650. }
  1651. }
  1652. });
  1653. id++;
  1654. }
  1655. App.ajax.send({
  1656. name: 'host.host_component.recommission_and_restart',
  1657. sender: this,
  1658. data: {
  1659. intervalTimeSeconds: 1,
  1660. tolerateSize: 1,
  1661. batches: batches
  1662. },
  1663. success: 'decommissionSuccessCallback',
  1664. error: 'decommissionErrorCallback'
  1665. });
  1666. },
  1667. /**
  1668. * Handler for host-menu items actions
  1669. * @param {object} option
  1670. * @method doAction
  1671. */
  1672. doAction: function (option) {
  1673. switch (option.context.action) {
  1674. case "deleteHost":
  1675. this.validateAndDeleteHost();
  1676. break;
  1677. case "startAllComponents":
  1678. if (!this.get('content.isNotHeartBeating')) this.doStartAllComponents();
  1679. break;
  1680. case "stopAllComponents":
  1681. if (!this.get('content.isNotHeartBeating')) this.doStopAllComponents();
  1682. break;
  1683. case "restartAllComponents":
  1684. if (!this.get('content.isNotHeartBeating')) this.doRestartAllComponents();
  1685. break;
  1686. case "onOffPassiveModeForHost":
  1687. this.onOffPassiveModeForHost(option.context);
  1688. break;
  1689. case "setRackId":
  1690. this.setRackIdForHost();
  1691. break;
  1692. }
  1693. },
  1694. /**
  1695. * Turn On/Off Passive Mode for host
  1696. * @param {object} context
  1697. * @method onOffPassiveModeForHost
  1698. */
  1699. onOffPassiveModeForHost: function (context) {
  1700. var state = context.active ? 'ON' : 'OFF';
  1701. var self = this;
  1702. var message = Em.I18n.t('hosts.host.details.for.postfix').format(context.label);
  1703. var popupInfo = Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off', this.get('content.hostName'));
  1704. if (state === 'OFF') {
  1705. var hostVersion = this.get('content.stackVersions') && this.get('content.stackVersions').findProperty('isCurrent').get('repoVersion'),
  1706. currentVersion = App.StackVersion.find().findProperty('isCurrent'),
  1707. clusterVersion = currentVersion && currentVersion.get('repositoryVersion.repositoryVersion');
  1708. if (hostVersion !== clusterVersion) {
  1709. var msg = Em.I18n.t("hosts.passiveMode.popup.version.mismatch").format(this.get('content.hostName'), clusterVersion);
  1710. popupInfo += '<br/><div class="alert alert-warning">' + msg + '</div>';
  1711. }
  1712. }
  1713. return App.showConfirmationPopup(function () {
  1714. self.hostPassiveModeRequest(state, message);
  1715. }, popupInfo);
  1716. },
  1717. /**
  1718. * Set rack id for host
  1719. * @method setRackIdForHost
  1720. */
  1721. setRackIdForHost: function () {
  1722. var hostNames = [{hostName: this.get('content.hostName')}];
  1723. var rack = this.get('content.rack');
  1724. var operationData = {message: Em.I18n.t('hosts.host.details.setRackId')};
  1725. hostsManagement.setRackInfo(operationData, hostNames, rack);
  1726. },
  1727. /**
  1728. * Send request to get passive state for host
  1729. * @param {string} state
  1730. * @param {string} message
  1731. * @method hostPassiveModeRequest
  1732. */
  1733. hostPassiveModeRequest: function (state, message) {
  1734. App.ajax.send({
  1735. name: 'bulk_request.hosts.passive_state',
  1736. sender: this,
  1737. data: {
  1738. hostNames: this.get('content.hostName'),
  1739. passive_state: state,
  1740. requestInfo: message
  1741. },
  1742. success: 'updateHost'
  1743. });
  1744. },
  1745. /**
  1746. * Success callback for receiving host passive state
  1747. * @param {object} data
  1748. * @param {object} opt
  1749. * @param {object} params
  1750. * @method updateHost
  1751. */
  1752. updateHost: function (data, opt, params) {
  1753. this.set('content.passiveState', params.passive_state);
  1754. batchUtils.infoPassiveState(params.passive_state);
  1755. },
  1756. /**
  1757. * Send request to get passive state for hostComponent
  1758. * @param {object} component - hostComponentn object
  1759. * @param {string} state
  1760. * @param {string} message
  1761. * @method hostPassiveModeRequest
  1762. */
  1763. updateComponentPassiveState: function (component, state, message) {
  1764. App.ajax.send({
  1765. name: 'common.host.host_component.passive',
  1766. sender: this,
  1767. data: {
  1768. hostName: this.get('content.hostName'),
  1769. componentName: component.get('componentName'),
  1770. component: component,
  1771. passive_state: state,
  1772. context: message
  1773. },
  1774. success: 'updateHostComponent'
  1775. });
  1776. },
  1777. /**
  1778. * Success callback for receiving hostComponent passive state
  1779. * @param {object} data
  1780. * @param {object} opt
  1781. * @param {object} params
  1782. * @method updateHost
  1783. */
  1784. updateHostComponent: function (data, opt, params) {
  1785. params.component.set('passiveState', params.passive_state);
  1786. batchUtils.infoPassiveState(params.passive_state);
  1787. },
  1788. /**
  1789. * Show confirmation popup for action "start all components"
  1790. * @method doStartAllComponents
  1791. */
  1792. doStartAllComponents: function () {
  1793. var self = this;
  1794. var components = this.get('serviceNonClientActiveComponents');
  1795. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1796. if (componentsLength > 0) {
  1797. return App.showConfirmationPopup(function () {
  1798. self.sendComponentCommand(components, Em.I18n.t('hosts.host.maintainance.startAllComponents.context'), App.HostComponentStatus.started);
  1799. });
  1800. }
  1801. },
  1802. /**
  1803. * Show confirmation popup for action "stop all components"
  1804. * @method doStopAllComponents
  1805. */
  1806. doStopAllComponents: function () {
  1807. var self = this;
  1808. var components = this.get('serviceNonClientActiveComponents');
  1809. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1810. if (componentsLength > 0) {
  1811. if (components.someProperty('componentName', 'NAMENODE') &&
  1812. this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').someProperty('workStatus', App.HostComponentStatus.started)) {
  1813. this.checkNnLastCheckpointTime(function () {
  1814. return App.showConfirmationPopup(function () {
  1815. self.sendComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'), App.HostComponentStatus.stopped);
  1816. });
  1817. });
  1818. } else {
  1819. return App.showConfirmationPopup(function () {
  1820. self.sendComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'), App.HostComponentStatus.stopped);
  1821. });
  1822. }
  1823. }
  1824. },
  1825. /**
  1826. * Show confirmation popup for action "restart all components"
  1827. * @method doRestartAllComponents
  1828. */
  1829. doRestartAllComponents: function () {
  1830. var self = this;
  1831. var components = this.get('serviceActiveComponents');
  1832. var componentsLength = Em.isNone(components) ? 0 : components.get('length');
  1833. if (componentsLength > 0) {
  1834. if (components.someProperty('componentName', 'NAMENODE') &&
  1835. this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').someProperty('workStatus', App.HostComponentStatus.started)) {
  1836. this.checkNnLastCheckpointTime(function () {
  1837. return App.showConfirmationPopup(function () {
  1838. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')), "HOST");
  1839. });
  1840. });
  1841. } else {
  1842. return App.showConfirmationPopup(function () {
  1843. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')), "HOST");
  1844. });
  1845. }
  1846. }
  1847. },
  1848. /**
  1849. * get info about host-components, exactly:
  1850. * - host-components grouped by status, features
  1851. * - flag, that indicate whether ZooKeeper Server is installed
  1852. * @return {Object}
  1853. */
  1854. getHostComponentsInfo: function () {
  1855. var componentsOnHost = this.get('content.hostComponents');
  1856. var allComponents = App.HostComponent.find();
  1857. var stoppedStates = [App.HostComponentStatus.stopped,
  1858. App.HostComponentStatus.install_failed,
  1859. App.HostComponentStatus.upgrade_failed,
  1860. App.HostComponentStatus.init,
  1861. App.HostComponentStatus.unknown];
  1862. var container = {
  1863. zkServerInstalled: false,
  1864. lastComponents: [],
  1865. masterComponents: [],
  1866. runningComponents: [],
  1867. nonDeletableComponents: [],
  1868. unknownComponents: [],
  1869. toDecommissionComponents: []
  1870. };
  1871. var self = this;
  1872. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  1873. componentsOnHost.forEach(function (cInstance) {
  1874. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  1875. container.zkServerInstalled = true;
  1876. }
  1877. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  1878. container.lastComponents.push(cInstance.get('displayName'));
  1879. }
  1880. var workStatus = cInstance.get('workStatus');
  1881. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  1882. container.masterComponents.push(cInstance.get('displayName'));
  1883. }
  1884. if (stoppedStates.indexOf(workStatus) < 0) {
  1885. container.runningComponents.push(cInstance.get('displayName'));
  1886. }
  1887. if (!cInstance.get('isDeletable')) {
  1888. container.nonDeletableComponents.push(cInstance.get('displayName'));
  1889. }
  1890. if (workStatus === App.HostComponentStatus.unknown) {
  1891. container.unknownComponents.push(cInstance.get('displayName'));
  1892. }
  1893. if (App.get('components.decommissionAllowed').contains(cInstance.get('componentName')) && !cInstance.get('view.isComponentRecommissionAvailable')) {
  1894. container.toDecommissionComponents.push(cInstance.get('displayName'));
  1895. }
  1896. });
  1897. }
  1898. return container;
  1899. },
  1900. /**
  1901. * Deletion of hosts not supported for this version
  1902. * @method validateAndDeleteHost
  1903. */
  1904. validateAndDeleteHost: function () {
  1905. var container = this.getHostComponentsInfo();
  1906. if (container.masterComponents.length > 0) {
  1907. this.raiseDeleteComponentsError(container, 'masterList');
  1908. return;
  1909. } else if (container.nonDeletableComponents.length > 0) {
  1910. this.raiseDeleteComponentsError(container, 'nonDeletableList');
  1911. return;
  1912. } else if (container.runningComponents.length > 0) {
  1913. this.raiseDeleteComponentsError(container, 'runningList');
  1914. return;
  1915. }
  1916. if (container.zkServerInstalled) {
  1917. var self = this;
  1918. return App.showConfirmationPopup(function () {
  1919. self.confirmDeleteHost(container);
  1920. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1921. } else {
  1922. this.confirmDeleteHost(container);
  1923. }
  1924. },
  1925. /**
  1926. * Show popup with info about reasons why host can't be deleted
  1927. * @param {string[]} components
  1928. * @param {string} type
  1929. * @method raiseDeleteComponentsError
  1930. */
  1931. raiseDeleteComponentsError: function (container, type) {
  1932. App.ModalPopup.show({
  1933. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1934. type: type,
  1935. showBodyEnd: function () {
  1936. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1937. }.property(),
  1938. container: container,
  1939. components: function(){
  1940. var container = this.get('container');
  1941. switch (this.get('type')) {
  1942. case 'masterList':
  1943. return container.masterComponents;
  1944. case 'nonDeletableList':
  1945. return container.nonDeletableComponents;
  1946. case 'runningList':
  1947. return container.runningComponents;
  1948. }
  1949. }.property('type'),
  1950. componentsStr: function () {
  1951. return this.get('components').join(", ");
  1952. }.property(),
  1953. componentsBody: function () {
  1954. return Em.I18n.t('hosts.cant.do.popup.' + type + '.body').format(this.get('components').length);
  1955. }.property(),
  1956. componentsBodyEnd: function () {
  1957. if (this.get('showBodyEnd')) {
  1958. return Em.I18n.t('hosts.cant.do.popup.' + type + '.body.end').format(App.get('components.decommissionAllowed').map(function(c){return App.format.role(c)}).join(", "));
  1959. }
  1960. return '';
  1961. }.property(),
  1962. bodyClass: Em.View.extend({
  1963. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1964. }),
  1965. secondary: null
  1966. });
  1967. },
  1968. /**
  1969. * Show confirmation popup to delete host
  1970. * @param {Object} container
  1971. * @method confirmDeleteHost
  1972. */
  1973. confirmDeleteHost: function (container) {
  1974. var self = this;
  1975. return App.ModalPopup.show({
  1976. header: Em.I18n.t('hosts.delete.popup.title'),
  1977. deletePopupBody: function () {
  1978. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1979. }.property(),
  1980. lastComponent: function () {
  1981. if (container.lastComponents && container.lastComponents.length) {
  1982. this.set('isChecked', false);
  1983. return true;
  1984. } else {
  1985. this.set('isChecked', true);
  1986. return false;
  1987. }
  1988. }.property(),
  1989. disablePrimary: function () {
  1990. return !this.get('isChecked');
  1991. }.property('isChecked'),
  1992. isChecked: false,
  1993. lastComponentError: Em.View.extend({
  1994. template: Em.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(container.lastComponents))
  1995. }),
  1996. unknownComponents: function () {
  1997. if (container.unknownComponents && container.unknownComponents.length) {
  1998. return container.unknownComponents.join(", ");
  1999. }
  2000. return '';
  2001. }.property(),
  2002. decommissionWarning: Em.View.extend({
  2003. template: Em.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg7').format(container.toDecommissionComponents.join(', ')))
  2004. }),
  2005. toDecommissionComponents: container.toDecommissionComponents,
  2006. bodyClass: Em.View.extend({
  2007. templateName: require('templates/main/host/details/doDeleteHostPopup')
  2008. }),
  2009. onPrimary: function () {
  2010. var popup = this;
  2011. var completeCallback = function () {
  2012. var remainingHosts = App.db.getSelectedHosts('mainHostController').removeObject(self.get('content.hostName'));
  2013. App.db.setSelectedHosts('mainHostController', remainingHosts);
  2014. popup.hide();
  2015. };
  2016. self.doDeleteHost(completeCallback);
  2017. }
  2018. });
  2019. },
  2020. /**
  2021. * send DELETE calls to components of host and after delete host itself
  2022. * @param completeCallback
  2023. * @method doDeleteHost
  2024. */
  2025. doDeleteHost: function (completeCallback) {
  2026. this.set('fromDeleteHost', true);
  2027. var allComponents = this.get('content.hostComponents');
  2028. var deleteError = null;
  2029. var dfd = $.Deferred();
  2030. var self = this;
  2031. if (allComponents.get('length') > 0) {
  2032. allComponents.forEach(function (component, index) {
  2033. var length = allComponents.get('length');
  2034. if (!deleteError) {
  2035. this._doDeleteHostComponent(component, function () {
  2036. deleteError = self.get('_deletedHostComponentResult');
  2037. if (index == length - 1) {
  2038. dfd.resolve();
  2039. }
  2040. });
  2041. }
  2042. }, this);
  2043. } else {
  2044. dfd.resolve();
  2045. }
  2046. dfd.done(function () {
  2047. if (!deleteError) {
  2048. App.ajax.send({
  2049. name: 'common.delete.host',
  2050. sender: self,
  2051. data: {
  2052. hostName: self.get('content.hostName')
  2053. },
  2054. callback: completeCallback,
  2055. success: 'deleteHostSuccessCallback',
  2056. error: 'deleteHostErrorCallback'
  2057. });
  2058. }
  2059. else {
  2060. completeCallback();
  2061. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  2062. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  2063. }
  2064. });
  2065. },
  2066. deleteHostSuccessCallback: function (data, rq, requestBody) {
  2067. var self = this;
  2068. App.router.get('updateController').updateHost(function () {
  2069. App.router.transitionTo('hosts.index');
  2070. });
  2071. if (!!(requestBody && requestBody.hostName))
  2072. App.hostsMapper.deleteRecord(App.Host.find().findProperty('hostName', requestBody.hostName));
  2073. App.router.get('clusterController').getAllHostNames();
  2074. },
  2075. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  2076. console.log('Error deleting host.');
  2077. console.log(textStatus);
  2078. console.log(errorThrown);
  2079. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  2080. var self = this;
  2081. var callback = function () {
  2082. self.loadConfigs();
  2083. };
  2084. self.isServiceMetricsLoaded(callback);
  2085. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  2086. },
  2087. /**
  2088. * Send command to server to restart all host components with stale configs
  2089. * @method restartAllStaleConfigComponents
  2090. */
  2091. restartAllStaleConfigComponents: function () {
  2092. var self = this;
  2093. return App.showConfirmationPopup(function () {
  2094. var staleComponents = self.get('content.componentsWithStaleConfigs');
  2095. batchUtils.restartHostComponents(staleComponents, Em.I18n.t('rollingrestart.context.allWithStaleConfigsOnSelectedHost').format(self.get('content.hostName')), "HOST");
  2096. });
  2097. },
  2098. /**
  2099. * open Reassign Master Wizard with selected component
  2100. * @param {object} event
  2101. * @method moveComponent
  2102. */
  2103. moveComponent: function (event) {
  2104. if ($(event.target).closest('li').hasClass('disabled')) {
  2105. return;
  2106. }
  2107. return App.showConfirmationPopup(function () {
  2108. var component = event.context;
  2109. var reassignMasterController = App.router.get('reassignMasterController');
  2110. reassignMasterController.saveComponentToReassign(component);
  2111. reassignMasterController.setCurrentStep('1');
  2112. App.router.transitionTo('reassign');
  2113. });
  2114. },
  2115. /**
  2116. * Restart clients host components to apply config changes
  2117. * @param {object} event
  2118. * @method refreshConfigs
  2119. */
  2120. refreshConfigs: function (event) {
  2121. var self = this;
  2122. var components = event.context;
  2123. if (components.get('length') > 0) {
  2124. return App.showConfirmationPopup(function () {
  2125. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allClientsOnSelectedHost').format(self.get('content.hostName')), "HOST");
  2126. });
  2127. }
  2128. },
  2129. toggleMaintenanceMode: function (event) {
  2130. var self = this;
  2131. var state = event.context.get('passiveState') === "ON" ? "OFF" : "ON";
  2132. var message = Em.I18n.t('passiveState.turn' + state.toCapital() + 'For').format(event.context.get('displayName'));
  2133. return App.showConfirmationPopup(function () {
  2134. self.updateComponentPassiveState(event.context, state, message);
  2135. });
  2136. },
  2137. downloadClientConfigs: function (event) {
  2138. componentsUtils.downloadClientConfigs.call(this, {
  2139. hostName: event.context.get('hostName'),
  2140. componentName: event.context.get('componentName'),
  2141. displayName: event.context.get('displayName')
  2142. });
  2143. },
  2144. installClients: function (event) {
  2145. var clientsToInstall = [],
  2146. clientsToAdd = [],
  2147. missedComponents = [],
  2148. dependentComponents = [],
  2149. self = this;
  2150. event.context.forEach(function (component) {
  2151. if (['INIT', 'INSTALL_FAILED'].contains(component.get('workStatus'))) {
  2152. clientsToInstall.push(component);
  2153. } else if (typeof component.get('workStatus') == 'undefined') {
  2154. clientsToAdd.push(component);
  2155. }
  2156. });
  2157. clientsToAdd.forEach(function (component, index, array) {
  2158. var dependencies = componentsUtils.checkComponentDependencies(component.get('componentName'), {
  2159. scope: 'host',
  2160. installedComponents: this.get('content.hostComponents').mapProperty('componentName')
  2161. }).reject(function (componentName) {
  2162. return array.mapProperty('componentName').contains(componentName);
  2163. });
  2164. if (dependencies.length) {
  2165. missedComponents.pushObjects(dependencies);
  2166. dependentComponents.push(component.get('displayName'));
  2167. }
  2168. }, this);
  2169. missedComponents = missedComponents.uniq();
  2170. if (missedComponents.length) {
  2171. var popupMessage = Em.I18n.t('host.host.addComponent.popup.clients.dependedComponents.body').format(stringUtils.getFormattedStringFromArray(dependentComponents),
  2172. stringUtils.getFormattedStringFromArray(missedComponents.map(function (componentName) {
  2173. return App.StackServiceComponent.find(componentName).get('displayName');
  2174. })));
  2175. App.showAlertPopup(Em.I18n.t('host.host.addComponent.popup.dependedComponents.header'), popupMessage);
  2176. } else {
  2177. App.get('router.mainAdminKerberosController').getSecurityType(function () {
  2178. App.get('router.mainAdminKerberosController').getKDCSessionState(function () {
  2179. var sendInstallCommand = function () {
  2180. if (clientsToInstall.length) {
  2181. self.sendComponentCommand(clientsToInstall, Em.I18n.t('host.host.details.installClients'), 'INSTALLED');
  2182. }
  2183. };
  2184. if (clientsToAdd.length) {
  2185. var message = stringUtils.getFormattedStringFromArray(clientsToAdd.mapProperty('displayName'));
  2186. var isManualKerberos = App.get('router.mainAdminKerberosController.isManualKerberos');
  2187. self.showAddComponentPopup(message, isManualKerberos, function () {
  2188. sendInstallCommand();
  2189. clientsToAdd.forEach(function (component) {
  2190. this.primary(component);
  2191. }, self);
  2192. });
  2193. } else {
  2194. sendInstallCommand();
  2195. }
  2196. });
  2197. }.bind(this));
  2198. }
  2199. },
  2200. /**
  2201. * On click handler for custom command from items menu
  2202. * @param context
  2203. */
  2204. executeCustomCommand: function(event) {
  2205. var controller = this;
  2206. var context = event.context;
  2207. return App.showConfirmationPopup(function() {
  2208. App.ajax.send({
  2209. name : 'service.item.executeCustomCommand',
  2210. sender: controller,
  2211. data : {
  2212. command : context.command,
  2213. context : context.context || Em.I18n.t('services.service.actions.run.executeCustomCommand.context').format(context.command),
  2214. hosts : context.hosts,
  2215. serviceName : context.service,
  2216. componentName : context.component
  2217. },
  2218. success : 'executeCustomCommandSuccessCallback',
  2219. error : 'executeCustomCommandErrorCallback'
  2220. });
  2221. });
  2222. },
  2223. executeCustomCommandSuccessCallback : function(data, ajaxOptions, params) {
  2224. if (data.Requests.id) {
  2225. App.router.get('backgroundOperationsController').showPopup();
  2226. } else {
  2227. console.warn('Error during execution of ' + params.command + ' custom command on' + params.componentName);
  2228. }
  2229. },
  2230. executeCustomCommandErrorCallback : function(data) {
  2231. var error = Em.I18n.t('services.service.actions.run.executeCustomCommand.error');
  2232. if(data && data.responseText){
  2233. try {
  2234. var json = $.parseJSON(data.responseText);
  2235. error += json.message;
  2236. } catch (err) {}
  2237. }
  2238. App.showAlertPopup(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), error);
  2239. console.warn('Error during executing custom command');
  2240. },
  2241. /**
  2242. * show popup confirmation of version installation
  2243. * @param event
  2244. */
  2245. installVersionConfirmation: function (event) {
  2246. var self = this;
  2247. return App.showConfirmationPopup(function () {
  2248. self.installVersion(event);
  2249. },
  2250. Em.I18n.t('hosts.host.stackVersions.install.confirmation').format(event.context.get('displayName'))
  2251. );
  2252. },
  2253. /**
  2254. * install HostStackVersion on host
  2255. * @param {object} event
  2256. */
  2257. installVersion: function (event) {
  2258. App.ajax.send({
  2259. name: 'host.stack_versions.install',
  2260. sender: this,
  2261. data: {
  2262. hostName: this.get('content.hostName'),
  2263. version: event.context
  2264. },
  2265. success: 'installVersionSuccessCallback'
  2266. });
  2267. },
  2268. /**
  2269. * success callback of <code>installVersion</code>
  2270. * on success set version status to INSTALLING
  2271. * @param {object} data
  2272. * @param {object} opt
  2273. * @param {object} params
  2274. */
  2275. installVersionSuccessCallback: function (data, opt, params) {
  2276. App.HostStackVersion.find(params.version.get('id')).set('status', 'INSTALLING');
  2277. App.db.set('repoVersionInstall', 'id', [data.Requests.id]);
  2278. App.clusterStatus.setClusterStatus({
  2279. wizardControllerName: this.get('name'),
  2280. localdb: App.db.data
  2281. });
  2282. },
  2283. /**
  2284. * Call callback after loading service metrics
  2285. * @param callback
  2286. */
  2287. isServiceMetricsLoaded: function(callback) {
  2288. App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(callback);
  2289. }
  2290. });