details.js 83 KB

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