details.js 61 KB

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