details.js 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  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. App.MainHostDetailsController = Em.Controller.extend({
  21. name: 'mainHostDetailsController',
  22. /**
  23. * Viewed host
  24. * @type {App.Host|null}
  25. */
  26. content: null,
  27. /**
  28. * Does user come from hosts page
  29. * @type {bool}
  30. */
  31. isFromHosts: false,
  32. /**
  33. * path to page visited before
  34. * @type {string}
  35. */
  36. referer: '',
  37. /**
  38. * Open dashboard page
  39. * @method routeHome
  40. */
  41. routeHome: function () {
  42. App.router.transitionTo('main.dashboard');
  43. },
  44. /**
  45. * Open summary page of the selected service
  46. * @param {object} event
  47. * @method routeToService
  48. */
  49. routeToService: function(event){
  50. var service = event.context;
  51. App.router.transitionTo('main.services.service.summary',service);
  52. },
  53. /**
  54. * List of active (not in passive state) host components
  55. * @type {Ember.Enumerable}
  56. */
  57. serviceActiveComponents: function() {
  58. return this.get('content.hostComponents').filterProperty('service.isInPassive',false);
  59. }.property('content.hostComponents'),
  60. /**
  61. * List of active host components which aren't clients
  62. * @type {Ember.Enumerable}
  63. */
  64. serviceNonClientActiveComponents: function() {
  65. return this.get('serviceActiveComponents').filterProperty('isClient',false);
  66. }.property('serviceActiveComponents'),
  67. /**
  68. * Default error-callback for ajax-requests in current page
  69. * @param {object} request
  70. * @param {object} ajaxOptions
  71. * @param {string} error
  72. * @param {object} opt
  73. * @param {object} params
  74. * @method ajaxErrorCallback
  75. */
  76. ajaxErrorCallback: function (request, ajaxOptions, error, opt, params) {
  77. console.log('error on change component host status');
  78. App.ajax.defaultErrorHandler(request, opt.url, opt.method);
  79. },
  80. /**
  81. * send command to server to start selected host component
  82. * @param {object} event
  83. * @method startComponent
  84. */
  85. startComponent: function (event) {
  86. var self = this;
  87. App.showConfirmationPopup(function() {
  88. var component = event.context;
  89. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  90. self.sendStartComponentCommand(component, context);
  91. });
  92. },
  93. /**
  94. * PUTs a command to server to start a component. If no
  95. * specific component is provided, all components are started.
  96. * @param {object} component When <code>null</code> all startable components are started.
  97. * @param {string} context Context under which this command is beign sent.
  98. * @method sendStartComponentCommand
  99. */
  100. sendStartComponentCommand: function(component, context) {
  101. var dataToSend = {
  102. RequestInfo : {
  103. "context" : context
  104. },
  105. Body:{
  106. HostRoles: {
  107. state: 'STARTED'
  108. }
  109. }
  110. };
  111. if (Em.isArray(component)) {
  112. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + component.mapProperty('componentName').join(',') + ")";
  113. App.ajax.send({
  114. name: 'host.host_components.stop',
  115. sender: this,
  116. data: {
  117. data: JSON.stringify(dataToSend),
  118. hostName: this.get('content.hostName'),
  119. component: component
  120. },
  121. success: 'stopComponentSuccessCallback',
  122. error: 'ajaxErrorCallback'
  123. });
  124. }
  125. else {
  126. App.ajax.send({
  127. name: 'host.host_component.stop',
  128. sender: this,
  129. data: {
  130. data: JSON.stringify(dataToSend),
  131. hostName: this.get('content.hostName'),
  132. componentName: component.get('componentName').toUpperCase(),
  133. component: component
  134. },
  135. success: 'startComponentSuccessCallback',
  136. error: 'ajaxErrorCallback'
  137. });
  138. }
  139. },
  140. /**
  141. * Success callback for start component(s) request
  142. * @param {object} data
  143. * @param {object} opt
  144. * @param {object} params
  145. * @method startComponentSuccessCallback
  146. */
  147. startComponentSuccessCallback: function(data, opt, params) {
  148. console.log('Send request for STARTING successfully');
  149. if (App.testMode) {
  150. if(Em.isArray(params.component)){
  151. var allComponents = this.get('content.hostComponents');
  152. allComponents.forEach(function(c){
  153. c.set('workStatus', App.HostComponentStatus.stopping);
  154. setTimeout(function(){
  155. c.set('workStatus', App.HostComponentStatus.stopped);
  156. },App.testModeDelayForActions);
  157. });
  158. } else {
  159. params.component.set('workStatus', App.HostComponentStatus.starting);
  160. setTimeout(function(){
  161. params.component.set('workStatus', App.HostComponentStatus.started);
  162. },App.testModeDelayForActions);
  163. }
  164. } else {
  165. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  166. }
  167. // load data (if we need to show this background operations popup) from persist
  168. App.router.get('applicationController').dataLoading().done(function (initValue) {
  169. if (initValue) {
  170. App.router.get('backgroundOperationsController').showPopup();
  171. }
  172. });
  173. },
  174. /**
  175. * Send command to server to delete selected host component
  176. * @param {object} event
  177. * @method deleteComponent
  178. */
  179. deleteComponent: function (event) {
  180. var self = this;
  181. var component = event.context;
  182. var componentName = component.get('componentName');
  183. var displayName = component.get('displayName');
  184. var isLastComponent = (App.HostComponent.find().filterProperty('componentName', componentName).get('length') === 1);
  185. App.ModalPopup.show({
  186. header: Em.I18n.t('popup.confirmation.commonHeader'),
  187. primary: Em.I18n.t('hosts.host.deleteComponent.popup.confirm'),
  188. bodyClass: Em.View.extend({
  189. templateName: require('templates/main/host/details/deleteComponentPopup')
  190. }),
  191. isChecked: false,
  192. disablePrimary: function () {
  193. return !this.get('isChecked');
  194. }.property('isChecked'),
  195. lastComponent: function() {
  196. if (isLastComponent) {
  197. this.set('isChecked', false);
  198. return true;
  199. } else {
  200. this.set('isChecked', true);
  201. return false;
  202. }
  203. }.property(),
  204. lastComponentError: Em.View.extend({
  205. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  206. }),
  207. restartNagiosMsg: Em.View.extend({
  208. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.msg2').format(displayName))
  209. }),
  210. deleteComponentMsg: function() {
  211. return Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(displayName);
  212. }.property(),
  213. onPrimary: function () {
  214. self._doDeleteHostComponent(component);
  215. self.set('redrawComponents', true);
  216. this.hide();
  217. }
  218. });
  219. },
  220. /**
  221. * Trigger to reset list of master/slaves components on the view
  222. * @type {bool}
  223. */
  224. redrawComponents: false,
  225. /**
  226. * Deletes the given host component, or all host components.
  227. *
  228. * @param {object|null} component When <code>null</code> all host components are deleted.
  229. * @return <code>null</code> when components get deleted.
  230. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  231. * when components failed to get deleted.
  232. * @method _doDeleteHostComponent
  233. */
  234. _doDeleteHostComponent: function(component) {
  235. if (component === null) {
  236. App.ajax.send({
  237. name: 'host.host_components.delete',
  238. sender: this,
  239. data: {
  240. hostName: this.get('content.hostName')
  241. },
  242. success: '_doDeleteHostComponentSuccessCallback',
  243. error: '_doDeleteHostComponentErrorCallback'
  244. });
  245. }
  246. else {
  247. App.ajax.send({
  248. name: 'host.host_component.delete',
  249. sender: this,
  250. data: {
  251. componentName: component.get('componentName').toUpperCase(),
  252. hostName: this.get('content.hostName')
  253. },
  254. success: '_doDeleteHostComponentSuccessCallback',
  255. error: '_doDeleteHostComponentErrorCallback'
  256. });
  257. }
  258. return this.get('_deletedHostComponentResult');
  259. },
  260. /**
  261. * Result of delete component(s) request
  262. * @type {object}
  263. */
  264. _deletedHostComponentResult: null,
  265. /**
  266. * Success callback for delete host component request
  267. * @method _doDeleteHostComponentSuccessCallback
  268. */
  269. _doDeleteHostComponentSuccessCallback: function() {
  270. this.set('_deletedHostComponentResult', null);
  271. },
  272. /**
  273. * Error-callback for delete host component request
  274. * @param {object} xhr
  275. * @param {string} textStatus
  276. * @param {object} errorThrown
  277. * @method _doDeleteHostComponentErrorCallback
  278. */
  279. _doDeleteHostComponentErrorCallback: function(xhr, textStatus, errorThrown) {
  280. console.log('Error deleting host component');
  281. console.log(textStatus);
  282. console.log(errorThrown);
  283. this.set('_deletedHostComponentResult', {xhr: xhr, url: url, method: 'DELETE'});
  284. },
  285. /**
  286. * Send command to server to upgrade selected host component
  287. * @param {object} event
  288. * @method upgradeComponent
  289. */
  290. upgradeComponent: function (event) {
  291. var self = this;
  292. var component = event.context;
  293. App.showConfirmationPopup(function() {
  294. App.ajax.send({
  295. name: 'host.host_component.upgrade',
  296. sender: self,
  297. data: {
  298. component: component,
  299. hostName: self.get('content.hostName'),
  300. componentName: component.get('componentName').toUpperCase(),
  301. data: JSON.stringify({
  302. RequestInfo : {
  303. "context" : Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  304. },
  305. Body:{
  306. HostRoles:{
  307. stack_id: 'HDP-1.2.2',
  308. state: 'INSTALLED'
  309. }
  310. }
  311. })
  312. },
  313. success: 'upgradeComponentSuccessCallback',
  314. error: 'ajaxErrorCallback'
  315. });
  316. });
  317. },
  318. /**
  319. * Success callback for upgrade host component request
  320. * @param {object} data
  321. * @param {object} opt
  322. * @param {object} params
  323. * @method upgradeComponentSuccessCallback
  324. */
  325. upgradeComponentSuccessCallback: function(data, opt, params) {
  326. console.log('Send request for UPGRADE successfully');
  327. if (App.testMode) {
  328. params.component.set('workStatus', App.HostComponentStatus.starting);
  329. setTimeout(function(){
  330. params.component.set('workStatus', App.HostComponentStatus.started);
  331. },App.testModeDelayForActions);
  332. } else {
  333. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  334. }
  335. // load data (if we need to show this background operations popup) from persist
  336. App.router.get('applicationController').dataLoading().done(function (initValue) {
  337. if (initValue) {
  338. App.router.get('backgroundOperationsController').showPopup();
  339. }
  340. });
  341. },
  342. /**
  343. * Send command to server to stop selected host component
  344. * @param {object} event
  345. * @method stopComponent
  346. */
  347. stopComponent: function (event) {
  348. var self = this;
  349. App.showConfirmationPopup(function() {
  350. var component = event.context;
  351. var context = Em.I18n.t('requestInfo.stopHostComponent')+ " " + component.get('displayName');
  352. self.sendStopComponentCommand(component, context);
  353. });
  354. },
  355. /**
  356. * PUTs a command to server to stop a component. If no
  357. * specific component is provided, all components are stopped.
  358. * @param {object} component When <code>null</code> all components are stopped.
  359. * @param {object} context Context under which this command is beign sent.
  360. * @method sendStopComponentCommand
  361. */
  362. sendStopComponentCommand: function(component, context) {
  363. var dataToSend = {
  364. RequestInfo : {
  365. "context" : context
  366. },
  367. Body:{
  368. HostRoles: {
  369. state: 'INSTALLED'
  370. }
  371. }
  372. };
  373. if (Em.isArray(component)) {
  374. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + component.mapProperty('componentName').join(',') + ")";
  375. App.ajax.send({
  376. name: 'host.host_components.stop',
  377. sender: this,
  378. data: {
  379. data: JSON.stringify(dataToSend),
  380. hostName: this.get('content.hostName'),
  381. component: component
  382. },
  383. success: 'stopComponentSuccessCallback'
  384. });
  385. }
  386. else {
  387. App.ajax.send({
  388. name: 'host.host_component.stop',
  389. sender: this,
  390. data: {
  391. data: JSON.stringify(dataToSend),
  392. hostName: this.get('content.hostName'),
  393. componentName: component.get('componentName').toUpperCase(),
  394. component: component
  395. },
  396. success: 'stopComponentSuccessCallback',
  397. error: 'ajaxErrorCallback'
  398. });
  399. }
  400. },
  401. /**
  402. * Success callback for stop host component request
  403. * @param {object} data
  404. * @param {object} opt
  405. * @param {object} params
  406. * @method stopComponentSuccessCallback
  407. */
  408. stopComponentSuccessCallback: function(data, opt, params) {
  409. console.log('Send request for STOPPING successfully');
  410. if (App.testMode) {
  411. if(Em.isArray(params.component)) {
  412. params.component.forEach(function(c){
  413. c.set('workStatus', App.HostComponentStatus.stopping);
  414. setTimeout(function(){
  415. c.set('workStatus', App.HostComponentStatus.stopped);
  416. },App.testModeDelayForActions);
  417. });
  418. }
  419. else {
  420. params.component.set('workStatus', App.HostComponentStatus.stopping);
  421. setTimeout(function() {
  422. params.component.set('workStatus', App.HostComponentStatus.stopped);
  423. },App.testModeDelayForActions);
  424. }
  425. }
  426. else {
  427. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  428. }
  429. // load data (if we need to show this background operations popup) from persist
  430. App.router.get('applicationController').dataLoading().done(function (initValue) {
  431. if (initValue) {
  432. App.router.get('backgroundOperationsController').showPopup();
  433. }
  434. });
  435. },
  436. /**
  437. * Send command to server to restart selected components
  438. * @param {object} event
  439. * @method restartComponent
  440. */
  441. restartComponent: function(event) {
  442. var self = this;
  443. var component = event.context;
  444. App.showConfirmationPopup(function(){
  445. batchUtils.restartHostComponents([component], Em.I18n.t('rollingrestart.context.selectedComponentOnSelectedHost').format(component.get('displayName')));
  446. });
  447. },
  448. /**
  449. * Send command to server to install selected host component
  450. * @param {object} event
  451. * @method addComponent
  452. */
  453. addComponent: function (event) {
  454. var self = this;
  455. var component = event.context;
  456. var componentName = component.get('componentName').toUpperCase().toString();
  457. var subComponentNames = component.get('subComponentNames');
  458. var displayName = component.get('displayName');
  459. var securityEnabled = App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus();
  460. if (componentName === 'ZOOKEEPER_SERVER') {
  461. App.showConfirmationPopup(function() {
  462. self.primary(component);
  463. }, Em.I18n.t('hosts.host.addComponent.addZooKeeper'));
  464. }
  465. else {
  466. if (securityEnabled && component.get('componentName') !== 'CLIENTS') {
  467. App.showConfirmationPopup(function() {
  468. self.primary(component);
  469. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName,self.get('content.hostName')));
  470. }
  471. else {
  472. var dn = displayName;
  473. if (subComponentNames !== null && subComponentNames.length > 0) {
  474. var dns = [];
  475. subComponentNames.forEach(function(scn){
  476. dns.push(App.format.role(scn));
  477. });
  478. dn += " ("+dns.join(", ")+")";
  479. }
  480. App.ModalPopup.show({
  481. primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'),
  482. header: Em.I18n.t('popup.confirmation.commonHeader'),
  483. addComponentMsg: function() {
  484. return Em.I18n.t('hosts.host.addComponent.msg').format(dn);
  485. }.property(),
  486. bodyClass: Em.View.extend({
  487. templateName: require('templates/main/host/details/addComponentPopup')
  488. }),
  489. restartNagiosMsg: Em.View.extend({
  490. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(dn))
  491. }),
  492. onPrimary: function () {
  493. this.hide();
  494. if (component.get('componentName') === 'CLIENTS') {
  495. // Clients component has many sub-components which
  496. // need to be installed.
  497. var scs = component.get('subComponentNames');
  498. scs.forEach(function (sc, index) {
  499. var c = Em.Object.create({
  500. displayName: App.format.role(sc),
  501. componentName: sc
  502. });
  503. self.primary(c);
  504. });
  505. }
  506. else {
  507. self.primary(component);
  508. }
  509. }
  510. });
  511. }
  512. }
  513. },
  514. /**
  515. * Send request to add host component
  516. * @param {App.HostComponent} component
  517. * @method primary
  518. */
  519. primary: function(component) {
  520. var self = this;
  521. var componentName = component.get('componentName').toUpperCase();
  522. var displayName = component.get('displayName');
  523. App.ajax.send({
  524. name: 'host.host_component.add_new_component',
  525. sender: self,
  526. data: {
  527. hostName: self.get('content.hostName'),
  528. component: component,
  529. data: JSON.stringify({
  530. RequestInfo: {
  531. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  532. },
  533. Body: {
  534. host_components: [
  535. {
  536. HostRoles: {
  537. component_name: componentName
  538. }
  539. }
  540. ]
  541. }
  542. })
  543. },
  544. success: 'addNewComponentSuccessCallback',
  545. error: 'ajaxErrorCallback'
  546. });
  547. },
  548. /**
  549. * Success callback for add host component request
  550. * @param {object} data
  551. * @param {object} opt
  552. * @param {object} params
  553. * @method addNewComponentSuccessCallback
  554. */
  555. addNewComponentSuccessCallback: function(data, opt, params) {
  556. console.log('Send request for ADDING NEW COMPONENT successfully');
  557. App.ajax.send({
  558. name: 'host.host_component.install_new_component',
  559. sender: this,
  560. data: {
  561. hostName: this.get('content.hostName'),
  562. componentName: params.component.get('componentName'),
  563. component: params.component,
  564. data: JSON.stringify({
  565. RequestInfo: {
  566. "context": Em.I18n.t('requestInfo.installNewHostComponent') + " " + params.component.get('displayName')
  567. },
  568. Body: {
  569. HostRoles: {
  570. state: 'INSTALLED'
  571. }
  572. }
  573. })
  574. },
  575. success: 'installNewComponentSuccessCallback',
  576. error: 'ajaxErrorCallback'
  577. });
  578. },
  579. /**
  580. * Success callback for install host component request (sent in <code>addNewComponentSuccessCallback</code>)
  581. * @param {object} data
  582. * @param {object} opt
  583. * @param {object} params
  584. * @method installNewComponentSuccessCallback
  585. */
  586. installNewComponentSuccessCallback: function(data, opt, params) {
  587. if (!data.Requests || !data.Requests.id) {
  588. return;
  589. }
  590. var self = this;
  591. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  592. if (App.testMode) {
  593. params.component.set('workStatus', App.HostComponentStatus.installing);
  594. setTimeout(function () {
  595. params.component.set('workStatus', App.HostComponentStatus.stopped);
  596. }, App.testModeDelayForActions);
  597. }
  598. else {
  599. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  600. }
  601. // load data (if we need to show this background operations popup) from persist
  602. App.router.get('applicationController').dataLoading().done(function (initValue) {
  603. if (initValue) {
  604. App.router.get('backgroundOperationsController').showPopup();
  605. }
  606. if (params.componentName === 'ZOOKEEPER_SERVER') {
  607. self.set('zkRequestId', data.Requests.id);
  608. self.addObserver('App.router.backgroundOperationsController.serviceTimestamp', self, self.checkZkConfigs);
  609. self.checkZkConfigs();
  610. }
  611. });
  612. },
  613. /**
  614. * Send command to server to resfresh configs of selected component
  615. * @param {object} event
  616. * @method refreshComponentConfigs
  617. */
  618. refreshComponentConfigs: function (event) {
  619. var self = this;
  620. App.showConfirmationPopup(function() {
  621. var component = event.context;
  622. var context = Em.I18n.t('requestInfo.refreshComponentConfigs').format(component.get('displayName'));
  623. self.sendRefreshComponentConfigsCommand(component, context);
  624. });
  625. },
  626. /**
  627. * PUTs a command to server to refresh configs of host component.
  628. * @param {object} component
  629. * @param {object} context Context under which this command is beign sent.
  630. * @method sendRefreshComponentConfigsCommand
  631. */
  632. sendRefreshComponentConfigsCommand: function (component, context) {
  633. resource_filters = [
  634. {
  635. service_name: component.get('service.serviceName'),
  636. component_name: component.get('componentName'),
  637. hosts: component.get('host.hostName')
  638. }
  639. ];
  640. App.ajax.send({
  641. name: 'host.host_component.refresh_configs',
  642. sender: this,
  643. data: {
  644. resource_filters: resource_filters,
  645. context: context
  646. },
  647. success: 'refreshComponentConfigsSuccessCallback'
  648. });
  649. },
  650. /**
  651. * Success callback for refresh host component configs request
  652. * @method refreshComponentConfigsSuccessCallback
  653. */
  654. refreshComponentConfigsSuccessCallback: function() {
  655. console.log('Send request for refresh configs successfully');
  656. // load data (if we need to show this background operations popup) from persist
  657. App.router.get('applicationController').dataLoading().done(function (showPopup) {
  658. if (showPopup) {
  659. App.router.get('backgroundOperationsController').showPopup();
  660. }
  661. });
  662. },
  663. /**
  664. * Load tags
  665. * @method checkZkConfigs
  666. */
  667. checkZkConfigs: function() {
  668. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId'));
  669. if (!bg) return;
  670. if (!bg.get('isRunning')) {
  671. this.loadConfigs();
  672. }
  673. },
  674. /**
  675. * Load configs
  676. * @method loadConfigs
  677. */
  678. loadConfigs: function() {
  679. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs);
  680. App.ajax.send({
  681. name: 'config.tags',
  682. sender: this,
  683. success: 'loadConfigsSuccessCallback'
  684. });
  685. },
  686. /**
  687. * Success callback for load configs request
  688. * @param {object} data
  689. * @method adConfigsSuccessCallback
  690. */
  691. loadConfigsSuccessCallback: function(data) {
  692. var urlParams = [];
  693. if (App.get('isHaEnabled')) {
  694. urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
  695. }
  696. if (App.Service.find().someProperty('serviceName', 'HBASE')) {
  697. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  698. }
  699. if (App.Service.find().someProperty('serviceName', 'HIVE')) {
  700. urlParams.push('(type=webhcat-site&tag=' + data.Clusters.desired_configs['webhcat-site'].tag + ')');
  701. }
  702. if (App.Service.find().someProperty('serviceName', 'STORM')) {
  703. urlParams.push('(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')');
  704. }
  705. if (!urlParams.length) {
  706. return;
  707. }
  708. App.ajax.send({
  709. name: 'reassign.load_configs',
  710. sender: this,
  711. data: {
  712. urlParams: urlParams.join('|')
  713. },
  714. success: 'setNewZkConfigs'
  715. });
  716. },
  717. /**
  718. * Set new values for some configs (based on available ZooKeeper Servers)
  719. * @param {object} data
  720. * @method setNewZkConfigs
  721. */
  722. setNewZkConfigs: function(data) {
  723. var configs = [];
  724. data.items.forEach(function (item) {
  725. configs[item.type] = item.properties;
  726. }, this);
  727. var zks = this.getZkServerHosts();
  728. var zks_with_port = '';
  729. zks.forEach(function(zk) {
  730. zks_with_port += zk + ':2181,';
  731. });
  732. zks_with_port = zks_with_port.slice(0,-1);
  733. if (App.get('isHaEnabled')) {
  734. configs['core-site']['ha.zookeeper.quorum'] = zks_with_port;
  735. }
  736. if (configs['hbase-site']) {
  737. configs['hbase-site']['hbase.zookeeper.quorum'] = zks.join(',');
  738. }
  739. if (configs['webhcat-site']) {
  740. configs['webhcat-site']['templeton.zookeeper.hosts'] = zks_with_port;
  741. }
  742. if (configs['storm-site']) {
  743. configs['storm-site']['storm.zookeeper.servers'] = JSON.stringify(zks).replace(/"/g, "'");
  744. }
  745. for (var site in configs) {
  746. if (!configs.hasOwnProperty(site)) continue;
  747. App.ajax.send({
  748. name: 'reassign.save_configs',
  749. sender: this,
  750. data: {
  751. siteName: site,
  752. properties: configs[site]
  753. }
  754. });
  755. }
  756. },
  757. /**
  758. * Is deleteHost action id fired
  759. * @type {bool}
  760. */
  761. fromDeleteHost: false,
  762. /**
  763. * Get list of hostnames where ZK Server is installed
  764. * @returns {string[]}
  765. * @method getZkServerHosts
  766. */
  767. getZkServerHosts: function() {
  768. var zks = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('host.hostName');
  769. if (this.get('fromDeleteHost')) {
  770. this.set('fromDeleteHost', false);
  771. return zks.without(this.get('content.hostName'));
  772. }
  773. return zks;
  774. },
  775. /**
  776. * Send command to server to install selected host component
  777. * @param {Object} event
  778. * @method installComponent
  779. */
  780. installComponent: function (event) {
  781. var self = this;
  782. var component = event.context;
  783. var componentName = component.get('componentName').toUpperCase();
  784. var displayName = component.get('displayName');
  785. App.ModalPopup.show({
  786. primary: Em.I18n.t('hosts.host.installComponent.popup.confirm'),
  787. header: Em.I18n.t('popup.confirmation.commonHeader'),
  788. installComponentMessage: function(){
  789. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  790. }.property(),
  791. restartNagiosMsg : Em.View.extend({
  792. template: Em.Handlebars.compile(Em.I18n.t('hosts.host.addComponent.note').format(displayName))
  793. }),
  794. bodyClass: Em.View.extend({
  795. templateName: require('templates/main/host/details/installComponentPopup')
  796. }),
  797. onPrimary: function () {
  798. this.hide();
  799. App.ajax.send({
  800. name: 'host.host_component.install',
  801. sender: self,
  802. data: {
  803. hostName: self.get('content.hostName'),
  804. componentName: componentName,
  805. component: component,
  806. data: JSON.stringify({
  807. RequestInfo: {
  808. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  809. },
  810. Body: {
  811. HostRoles: {
  812. state: 'INSTALLED'
  813. }
  814. }
  815. })
  816. },
  817. success: 'installComponentSuccessCallback',
  818. error: 'ajaxErrorCallback'
  819. });
  820. }
  821. });
  822. },
  823. /**
  824. * Success callback for install component request
  825. * @param {object} data
  826. * @param {object} opt
  827. * @param {object} params
  828. * @method installComponentSuccessCallback
  829. */
  830. installComponentSuccessCallback: function(data, opt, params) {
  831. console.log('Send request for REINSTALL COMPONENT successfully');
  832. if (App.testMode) {
  833. params.component.set('workStatus', App.HostComponentStatus.installing);
  834. setTimeout(function () {
  835. params.component.set('workStatus', App.HostComponentStatus.stopped);
  836. }, App.testModeDelayForActions);
  837. } else {
  838. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  839. }
  840. // load data (if we need to show this background operations popup) from persist
  841. App.router.get('applicationController').dataLoading().done(function (initValue) {
  842. if (initValue) {
  843. App.router.get('backgroundOperationsController').showPopup();
  844. }
  845. });
  846. },
  847. /**
  848. * Send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
  849. * @param {App.HostComponent} component
  850. * @method decommission
  851. */
  852. decommission: function(component) {
  853. var self = this;
  854. App.showConfirmationPopup(function(){
  855. var svcName = component.get('service.serviceName');
  856. var hostName = self.get('content.hostName');
  857. // HDFS service, decommission DataNode
  858. if (svcName === "HDFS") {
  859. self.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
  860. }
  861. // YARN service, decommission NodeManager
  862. if (svcName === "YARN") {
  863. self.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  864. }
  865. // MAPREDUCE service, decommission TaskTracker
  866. if (svcName === "MAPREDUCE") {
  867. self.doDecommission(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  868. }
  869. // HBASE service, decommission RegionServer
  870. if (svcName === "HBASE") {
  871. self.warnBeforeDecommission(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  872. }
  873. // load data (if we need to show this background operations popup) from persist
  874. App.router.get('applicationController').dataLoading().done(function (initValue) {
  875. if (initValue) {
  876. App.router.get('backgroundOperationsController').showPopup();
  877. }
  878. });
  879. });
  880. },
  881. /**
  882. * Send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
  883. * @param {App.HostComponent} component
  884. * @method recommission
  885. */
  886. recommission: function(component){
  887. var self = this;
  888. App.showConfirmationPopup(function(){
  889. var svcName = component.get('service.serviceName');
  890. var hostName = self.get('content.hostName');
  891. // HDFS service, Recommission datanode
  892. if (svcName === "HDFS") {
  893. self.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE");
  894. }
  895. // YARN service, Recommission nodeManager
  896. if (svcName === "YARN") {
  897. self.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  898. }
  899. // MAPREDUCE service, Recommission taskTracker
  900. if (svcName === "MAPREDUCE") {
  901. self.doRecommissionAndRestart(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  902. }
  903. // HBASE service, Recommission RegionServer
  904. if (svcName === "HBASE") {
  905. self.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  906. }
  907. // load data (if we need to show this background operations popup) from persist
  908. App.router.get('applicationController').dataLoading().done(function (initValue) {
  909. if (initValue) {
  910. App.router.get('backgroundOperationsController').showPopup();
  911. }
  912. });
  913. });
  914. },
  915. /**
  916. * Performs Decommission (for DN, TT and NM)
  917. * @param {string} hostName
  918. * @param {string} serviceName
  919. * @param {string} componentName
  920. * @param {string} slaveType
  921. * @method doDecommission
  922. */
  923. doDecommission: function(hostName, serviceName, componentName, slaveType){
  924. var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
  925. var context = Em.I18n.t(contextNameString);
  926. App.ajax.send({
  927. name: 'host.host_component.decommission_slave',
  928. sender: this,
  929. data: {
  930. context: context,
  931. command: 'DECOMMISSION',
  932. hostName: hostName,
  933. serviceName: serviceName ,
  934. componentName: componentName,
  935. slaveType: slaveType
  936. },
  937. success: 'decommissionSuccessCallback',
  938. error: 'decommissionErrorCallback'
  939. });
  940. },
  941. /**
  942. * Recomends user to put component in MM before decommision (for HBASE only)
  943. * @method warnBeforeDecommission
  944. * @param {string[]} hostNames - list of host when run from bulk operations or current host
  945. * @param {string} serviceName - serviceName
  946. * @param {string} componentName - master compoent name
  947. * @param {string} slaveType - slave component name
  948. */
  949. warnBeforeDecommission: function(hostNames, serviceName, componentName, slaveType) {
  950. if (this.get('content.hostComponents').findProperty('componentName', componentName).get('passiveState') == "OFF") {
  951. App.ModalPopup.show({
  952. header: Em.I18n.t('common.warning'),
  953. message: function(){
  954. return Em.I18n.t('hostPopup.reccomendation.beforeDecommission').format(App.format.components[componentName]);
  955. }.property(),
  956. bodyClass: Em.View.extend({
  957. template: Em.Handlebars.compile('<div class="alert alert-warning">{{message}}</div>')
  958. }),
  959. secondary: false
  960. });
  961. } else {
  962. this.doDecommissionRegionServer(hostNames, serviceName, componentName, slaveType);
  963. }
  964. },
  965. /**
  966. * Performs Decommission (for RegionServer)
  967. * @method doDecommissionRegionServer
  968. * @param {string[]} hostNames - list of host when run from bulk operations or current host
  969. * @param {string} serviceName - serviceName
  970. * @param {string} componentName - master compoent name
  971. * @param {string} slaveType - slave component name
  972. */
  973. doDecommissionRegionServer: function(hostNames, serviceName, componentName, slaveType){
  974. App.ajax.send({
  975. name: 'host.host_component.recommission_and_restart',
  976. sender: this,
  977. data: {
  978. intervalTimeSeconds: 1,
  979. tolerateSize : 0,
  980. batches:[
  981. {
  982. "order_id" : 1,
  983. "type" : "POST",
  984. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  985. "RequestBodyInfo" : {
  986. "RequestInfo" : {
  987. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  988. "command" : "DECOMMISSION",
  989. "parameters" : {
  990. "slave_type": slaveType,
  991. "excluded_hosts": hostNames
  992. }
  993. },
  994. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  995. }
  996. },
  997. {
  998. "order_id": 2,
  999. "type": "PUT",
  1000. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  1001. "RequestBodyInfo" : {
  1002. "RequestInfo" : {
  1003. context: Em.I18n.t('hosts.host.regionserver.decommission.batch2'),
  1004. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  1005. },
  1006. "Body": {
  1007. HostRoles: {
  1008. state: "INSTALLED"
  1009. }
  1010. }
  1011. }
  1012. },
  1013. {
  1014. "order_id" : 3,
  1015. "type" : "POST",
  1016. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1017. "RequestBodyInfo" : {
  1018. "RequestInfo" : {
  1019. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  1020. "command" : "DECOMMISSION",
  1021. "service_name" : serviceName,
  1022. "component_name" : componentName,
  1023. "parameters" : {
  1024. "slave_type": slaveType,
  1025. "excluded_hosts": hostNames,
  1026. "mark_draining_only": "true"
  1027. }
  1028. }
  1029. }
  1030. }
  1031. ]
  1032. },
  1033. success: 'decommissionSuccessCallback',
  1034. error: 'decommissionErrorCallback'
  1035. });
  1036. },
  1037. /**
  1038. * Error callback for decommission requests
  1039. * @param {object} request
  1040. * @param {object} ajaxOptions
  1041. * @param {string} error
  1042. * @method decommissionErrorCallback
  1043. */
  1044. decommissionErrorCallback: function (request, ajaxOptions, error) {
  1045. console.log('ERROR: '+ error);
  1046. },
  1047. /**
  1048. * Success ajax response for Recommission/Decommission slaves
  1049. * @param {object} data
  1050. * @method decommissionSuccessCallback
  1051. */
  1052. decommissionSuccessCallback: function(data) {
  1053. if(data && (data.Requests || data.resources[0].RequestSchedule) ) {
  1054. if (!App.testMode) {
  1055. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  1056. }
  1057. // load data (if we need to show this background operations popup) from persist
  1058. App.router.get('applicationController').dataLoading().done(function (initValue) {
  1059. if (initValue) {
  1060. App.router.get('backgroundOperationsController').showPopup();
  1061. }
  1062. });
  1063. }
  1064. else {
  1065. console.log('cannot get request id from ', data);
  1066. }
  1067. },
  1068. /**
  1069. * Performs Recommission and Start
  1070. * @param {string} hostNames
  1071. * @param {string} serviceName
  1072. * @param {string} componentName
  1073. * @param {string} slaveType
  1074. * @method doRecommissionAndStart
  1075. */
  1076. doRecommissionAndStart: function(hostNames, serviceName, componentName, slaveType){
  1077. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  1078. var context_1 = Em.I18n.t(contextNameString_1);
  1079. var contextNameString_2 = 'requestInfo.startHostComponent.' + slaveType.toLowerCase();
  1080. var startContext = Em.I18n.t(contextNameString_2);
  1081. App.ajax.send({
  1082. name: 'host.host_component.recommission_and_restart',
  1083. sender: this,
  1084. data: {
  1085. intervalTimeSeconds: 1,
  1086. tolerateSize : 1,
  1087. batches:[
  1088. {
  1089. "order_id" : 1,
  1090. "type" : "POST",
  1091. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1092. "RequestBodyInfo" : {
  1093. "RequestInfo" : {
  1094. "context" : context_1,
  1095. "command" : "DECOMMISSION",
  1096. "parameters" : {
  1097. "slave_type": slaveType,
  1098. "included_hosts": hostNames
  1099. }
  1100. },
  1101. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  1102. }
  1103. },
  1104. {
  1105. "order_id": 2,
  1106. "type": "PUT",
  1107. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/host_components",
  1108. "RequestBodyInfo" : {
  1109. "RequestInfo" : {
  1110. context: startContext,
  1111. query: 'HostRoles/component_name=' + slaveType + '&HostRoles/host_name.in(' + hostNames + ')&HostRoles/maintenance_state=OFF'
  1112. },
  1113. "Body": {
  1114. HostRoles: {
  1115. state: "STARTED"
  1116. }
  1117. }
  1118. }
  1119. }
  1120. ]
  1121. },
  1122. success: 'decommissionSuccessCallback',
  1123. error: 'decommissionErrorCallback'
  1124. });
  1125. },
  1126. /**
  1127. * Performs Recommission and Restart
  1128. * @param {string} hostNames
  1129. * @param {string} serviceName
  1130. * @param {string} componentName
  1131. * @param {string} slaveType
  1132. * @method doRecommissionAndStart
  1133. */
  1134. doRecommissionAndRestart: function(hostNames, serviceName, componentName, slaveType){
  1135. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  1136. var context_1 = Em.I18n.t(contextNameString_1);
  1137. var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
  1138. var context_2 = Em.I18n.t(contextNameString_2);
  1139. App.ajax.send({
  1140. name: 'host.host_component.recommission_and_restart',
  1141. sender: this,
  1142. data: {
  1143. intervalTimeSeconds: 1,
  1144. tolerateSize : 1,
  1145. batches:[
  1146. {
  1147. "order_id" : 1,
  1148. "type" : "POST",
  1149. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1150. "RequestBodyInfo" : {
  1151. "RequestInfo" : {
  1152. "context" : context_1,
  1153. "command" : "DECOMMISSION",
  1154. "parameters" : {
  1155. "slave_type": slaveType,
  1156. "included_hosts": hostNames
  1157. }
  1158. },
  1159. "Requests/resource_filters": [{"service_name" : serviceName, "component_name" : componentName}]
  1160. }
  1161. },
  1162. {
  1163. "order_id" : 2,
  1164. "type" : "POST",
  1165. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  1166. "RequestBodyInfo" : {
  1167. "RequestInfo" : {
  1168. "context" : context_2,
  1169. "command" : "RESTART",
  1170. "service_name" : serviceName,
  1171. "component_name" : slaveType,
  1172. "hosts" : hostNames
  1173. }
  1174. }
  1175. }
  1176. ]
  1177. },
  1178. success: 'decommissionSuccessCallback',
  1179. error: 'decommissionErrorCallback'
  1180. });
  1181. },
  1182. /**
  1183. * Handler for host-menu items actions
  1184. * @param {object} option
  1185. * @method doAction
  1186. */
  1187. doAction: function(option) {
  1188. switch (option.context.action) {
  1189. case "deleteHost":
  1190. this.validateAndDeleteHost();
  1191. break;
  1192. case "startAllComponents":
  1193. if (!this.get('content.isNotHeartBeating')) this.doStartAllComponents();
  1194. break;
  1195. case "stopAllComponents":
  1196. if (!this.get('content.isNotHeartBeating')) this.doStopAllComponents();
  1197. break;
  1198. case "restartAllComponents":
  1199. if (!this.get('content.isNotHeartBeating')) this.doRestartAllComponents();
  1200. break;
  1201. case "onOffPassiveModeForHost":
  1202. this.onOffPassiveModeForHost(option.context);
  1203. break;
  1204. default:
  1205. break;
  1206. }
  1207. },
  1208. /**
  1209. * Turn On/Off Passive Mode for host
  1210. * @param {object} context
  1211. * @method onOffPassiveModeForHost
  1212. */
  1213. onOffPassiveModeForHost: function(context) {
  1214. var state = context.active ? 'ON' : 'OFF';
  1215. var self = this;
  1216. var message = context.label + ' for host';
  1217. App.showConfirmationPopup(function() {
  1218. self.hostPassiveModeRequest(state, message);
  1219. },
  1220. Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off',this.get('content.hostName'))
  1221. );
  1222. },
  1223. /**
  1224. * Send request to get passive state for host
  1225. * @param {string} state
  1226. * @param {string} message
  1227. * @method hostPassiveModeRequest
  1228. */
  1229. hostPassiveModeRequest: function(state,message) {
  1230. App.ajax.send({
  1231. name: 'bulk_request.hosts.passive_state',
  1232. sender: this,
  1233. data: {
  1234. hostNames: this.get('content.hostName'),
  1235. passive_state: state,
  1236. requestInfo: message
  1237. },
  1238. success: 'updateHost'
  1239. });
  1240. },
  1241. /**
  1242. * Success callback for receiving host passive state
  1243. * @param {object} data
  1244. * @param {object} opt
  1245. * @param {object} params
  1246. * @method updateHost
  1247. */
  1248. updateHost: function(data, opt, params) {
  1249. this.set('content.passiveState', params.passive_state);
  1250. App.router.get('clusterController').loadUpdatedStatus(function(){
  1251. batchUtils.infoPassiveState(params.passive_state);
  1252. });
  1253. },
  1254. /**
  1255. * Show confirmation popup for action "start all components"
  1256. * @method doStartAllComponents
  1257. */
  1258. doStartAllComponents: function() {
  1259. var self = this;
  1260. var components = this.get('serviceNonClientActiveComponents');
  1261. var componentsLength = components == null ? 0 : components.get('length');
  1262. if (componentsLength > 0) {
  1263. App.showConfirmationPopup(function() {
  1264. self.sendStartComponentCommand(components, Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  1265. });
  1266. }
  1267. },
  1268. /**
  1269. * Show confirmation popup for action "stop all components"
  1270. * @method doStopAllComponents
  1271. */
  1272. doStopAllComponents: function() {
  1273. var self = this;
  1274. var components = this.get('serviceNonClientActiveComponents');
  1275. var componentsLength = components == null ? 0 : components.get('length');
  1276. if (componentsLength > 0) {
  1277. App.showConfirmationPopup(function() {
  1278. self.sendStopComponentCommand(components, Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  1279. });
  1280. }
  1281. },
  1282. /**
  1283. * Show confirmation popup for action "restart all components"
  1284. * @method doRestartAllComponents
  1285. */
  1286. doRestartAllComponents: function() {
  1287. var self = this;
  1288. var components = this.get('serviceActiveComponents');
  1289. var componentsLength = components == null ? 0 : components.get('length');
  1290. if (componentsLength > 0) {
  1291. App.showConfirmationPopup(function() {
  1292. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allOnSelectedHost').format(self.get('content.hostName')));
  1293. });
  1294. }
  1295. },
  1296. /**
  1297. * Deletion of hosts not supported for this version
  1298. * @method validateAndDeleteHost
  1299. */
  1300. validateAndDeleteHost: function () {
  1301. if (!App.supports.deleteHost) {
  1302. return;
  1303. }
  1304. var stoppedStates = [App.HostComponentStatus.stopped,
  1305. App.HostComponentStatus.install_failed,
  1306. App.HostComponentStatus.upgrade_failed,
  1307. App.HostComponentStatus.init,
  1308. App.HostComponentStatus.unknown];
  1309. var masterComponents = [];
  1310. var runningComponents = [];
  1311. var unknownComponents = [];
  1312. var nonDeletableComponents = [];
  1313. var lastComponents = [];
  1314. var componentsOnHost = this.get('content.hostComponents');
  1315. var allComponents = App.HostComponent.find();
  1316. var zkServerInstalled = false;
  1317. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  1318. componentsOnHost.forEach(function (cInstance) {
  1319. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  1320. zkServerInstalled = true;
  1321. }
  1322. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  1323. lastComponents.push(cInstance.get('displayName'));
  1324. }
  1325. var workStatus = cInstance.get('workStatus');
  1326. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  1327. masterComponents.push(cInstance.get('displayName'));
  1328. }
  1329. if (stoppedStates.indexOf(workStatus) < 0) {
  1330. runningComponents.push(cInstance.get('displayName'));
  1331. }
  1332. if (!cInstance.get('isDeletable')) {
  1333. nonDeletableComponents.push(cInstance.get('displayName'));
  1334. }
  1335. if (workStatus === App.HostComponentStatus.unknown) {
  1336. unknownComponents.push(cInstance.get('displayName'));
  1337. }
  1338. });
  1339. }
  1340. if (masterComponents.length > 0) {
  1341. this.raiseDeleteComponentsError(masterComponents, 'masterList');
  1342. return;
  1343. } else if (nonDeletableComponents.length > 0) {
  1344. this.raiseDeleteComponentsError(nonDeletableComponents, 'nonDeletableList');
  1345. return;
  1346. } else if (runningComponents.length > 0) {
  1347. this.raiseDeleteComponentsError(runningComponents, 'runningList');
  1348. return;
  1349. }
  1350. if (zkServerInstalled) {
  1351. var self = this;
  1352. App.showConfirmationPopup(function() {
  1353. self._doDeleteHost(unknownComponents, lastComponents);
  1354. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1355. }
  1356. else {
  1357. this._doDeleteHost(unknownComponents, lastComponents);
  1358. }
  1359. },
  1360. /**
  1361. * Show popup with info about reasons why host can't be deleted
  1362. * @param {string[]} components
  1363. * @param {string} type
  1364. * @method raiseDeleteComponentsError
  1365. */
  1366. raiseDeleteComponentsError: function (components, type) {
  1367. App.ModalPopup.show({
  1368. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1369. type: type,
  1370. showBodyEnd: function() {
  1371. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1372. }.property(),
  1373. components: components,
  1374. componentsStr: function() {
  1375. return this.get('components').join(", ");
  1376. }.property(),
  1377. componentsBody: function() {
  1378. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body').format(this.get('components').length);
  1379. }.property(),
  1380. componentsBodyEnd: function() {
  1381. if (this.get('showBodyEnd')) {
  1382. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body.end');
  1383. }
  1384. return '';
  1385. }.property(),
  1386. bodyClass: Em.View.extend({
  1387. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1388. }),
  1389. secondary: null
  1390. })
  1391. },
  1392. /**
  1393. * Show confirmation popup to delete host
  1394. * @param {string[]} unknownComponents
  1395. * @param {string[]} lastComponents
  1396. * @method _doDeleteHost
  1397. */
  1398. _doDeleteHost: function(unknownComponents,lastComponents) {
  1399. var self = this;
  1400. App.ModalPopup.show({
  1401. header: Em.I18n.t('hosts.delete.popup.title'),
  1402. deletePopupBody: function() {
  1403. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1404. }.property(),
  1405. lastComponent: function() {
  1406. if (lastComponents && lastComponents.length) {
  1407. this.set('isChecked', false);
  1408. return true;
  1409. } else {
  1410. this.set('isChecked', true);
  1411. return false;
  1412. }
  1413. }.property(),
  1414. disablePrimary: function () {
  1415. return !this.get('isChecked');
  1416. }.property('isChecked'),
  1417. isChecked: false,
  1418. lastComponentError: Em.View.extend({
  1419. template: Em.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  1420. }),
  1421. unknownComponents: function() {
  1422. if (unknownComponents && unknownComponents.length) {
  1423. return unknownComponents.join(", ");
  1424. }
  1425. return '';
  1426. }.property(),
  1427. bodyClass: Em.View.extend({
  1428. templateName: require('templates/main/host/details/doDeleteHostPopup')
  1429. }),
  1430. onPrimary: function() {
  1431. self.set('fromDeleteHost', true);
  1432. var allComponents = self.get('content.hostComponents');
  1433. var deleteError = null;
  1434. allComponents.forEach(function(component){
  1435. if (!deleteError) {
  1436. deleteError = self._doDeleteHostComponent(component);
  1437. }
  1438. });
  1439. if (!deleteError) {
  1440. App.ajax.send({
  1441. name: 'host.delete',
  1442. sender: this,
  1443. data: {
  1444. hostName: self.get('content.hostName')
  1445. },
  1446. success: 'deleteHostSuccessCallback',
  1447. error: 'deleteHostErrorCallback'
  1448. });
  1449. }
  1450. else {
  1451. this.hide();
  1452. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  1453. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  1454. }
  1455. },
  1456. deleteHostSuccessCallback: function(data) {
  1457. var dialogSelf = this;
  1458. App.router.get('updateController').updateHost(function(){
  1459. self.loadConfigs();
  1460. dialogSelf.hide();
  1461. App.router.transitionTo('hosts.index');
  1462. });
  1463. },
  1464. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  1465. console.log('Error deleting host.');
  1466. console.log(textStatus);
  1467. console.log(errorThrown);
  1468. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  1469. self.loadConfigs();
  1470. this.hide();
  1471. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  1472. }
  1473. })
  1474. },
  1475. /**
  1476. * Send command to server to restart all host components with stale configs
  1477. * @method restartAllStaleConfigComponents
  1478. */
  1479. restartAllStaleConfigComponents: function() {
  1480. var self = this;
  1481. App.showConfirmationPopup(function () {
  1482. var staleComponents = self.get('content.componentsWithStaleConfigs');
  1483. batchUtils.restartHostComponents(staleComponents, Em.I18n.t('rollingrestart.context.allWithStaleConfigsOnSelectedHost').format(self.get('content.hostName')));
  1484. });
  1485. },
  1486. /**
  1487. * open Reassign Master Wizard with selected component
  1488. * @param {object} event
  1489. * @method moveComponent
  1490. */
  1491. moveComponent: function (event) {
  1492. App.showConfirmationPopup(function() {
  1493. var component = event.context;
  1494. var reassignMasterController = App.router.get('reassignMasterController');
  1495. reassignMasterController.saveComponentToReassign(component);
  1496. reassignMasterController.getSecurityStatus();
  1497. reassignMasterController.setCurrentStep('1');
  1498. App.router.transitionTo('reassign');
  1499. });
  1500. },
  1501. /**
  1502. * Restart clients host components to apply config changes
  1503. * @param {object} event
  1504. * @method refreshConfigs
  1505. */
  1506. refreshConfigs: function(event) {
  1507. var self = this;
  1508. var components = event.context.filter(function(component) {
  1509. return component.get('staleConfigs');
  1510. });
  1511. if (components.get('length') > 0) {
  1512. App.showConfirmationPopup(function() {
  1513. batchUtils.restartHostComponents(components, Em.I18n.t('rollingrestart.context.allClientsOnSelectedHost').format(self.get('content.hostName')));
  1514. });
  1515. }
  1516. }
  1517. });