details.js 76 KB

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