step3_controller.js 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553
  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 lazyloading = require('utils/lazy_loading');
  20. var numberUtils = require('utils/number_utils');
  21. App.WizardStep3Controller = Em.Controller.extend({
  22. name: 'wizardStep3Controller',
  23. hosts: [],
  24. content: [],
  25. bootHosts: [],
  26. registeredHosts: [],
  27. hostCheckWarnings: [],
  28. repoCategoryWarnings: [],
  29. diskCategoryWarnings: [],
  30. jdkCategoryWarnings: null,
  31. registrationStartedAt: null,
  32. requestId: 0,
  33. /**
  34. * Timeout for registration
  35. * Based on <code>installOptions.manualInstall</code>
  36. * @type {number}
  37. */
  38. registrationTimeoutSecs: function () {
  39. return this.get('content.installOptions.manualInstall') ? 15 : 120;
  40. }.property('content.installOptions.manualInstall'),
  41. /**
  42. * Bootstrap calls are stopped
  43. * @type {bool}
  44. */
  45. stopBootstrap: false,
  46. /**
  47. * is Submit button disabled
  48. * @type {bool}
  49. */
  50. isSubmitDisabled: true,
  51. /**
  52. * is Retry button disabled
  53. * @type {bool}
  54. */
  55. isRetryDisabled: true,
  56. /**
  57. * @type {bool}
  58. */
  59. isLoaded: false,
  60. /**
  61. * Polls count
  62. * @type {number}
  63. */
  64. numPolls: 0,
  65. /**
  66. * Is hosts registration in progress
  67. * @type {bool}
  68. */
  69. isRegistrationInProgress: true,
  70. /**
  71. * Are some registered hosts which are not added by user
  72. * @type {bool}
  73. */
  74. hasMoreRegisteredHosts: false,
  75. /**
  76. * List of installed hostnames
  77. * @type {string[]}
  78. */
  79. hostsInCluster: function () {
  80. return this.get('content.installedHosts').getEach('hostName');
  81. }.property('content.installedHosts'),
  82. /**
  83. * All hosts warnings
  84. * @type {object[]}
  85. */
  86. warnings: [],
  87. /**
  88. * Warnings grouped by host
  89. * @type {Ember.Enumerable}
  90. */
  91. warningsByHost: [],
  92. /**
  93. * Timeout for "warning"-requests
  94. * @type {number}
  95. */
  96. warningsTimeInterval: 60000,
  97. /**
  98. * Are hosts warnings loaded
  99. * @type {bool}
  100. */
  101. isWarningsLoaded: function () {
  102. return this.get('isJDKWarningsLoaded') && this.get('isHostsWarningsLoaded');
  103. }.property('isJDKWarningsLoaded', 'isHostsWarningsLoaded'),
  104. /**
  105. * Check are hosts have any warnings
  106. * @type {bool}
  107. */
  108. isHostHaveWarnings: function () {
  109. return this.get('warnings.length') > 0;
  110. }.property('warnings'),
  111. /**
  112. * Should warnings-box be visible
  113. * @type {bool}
  114. */
  115. isWarningsBoxVisible: function () {
  116. return (App.testMode) ? true : !this.get('isRegistrationInProgress');
  117. }.property('isRegistrationInProgress'),
  118. /**
  119. * Progress value for "update hosts status" process
  120. * @type {number}
  121. */
  122. checksUpdateProgress: 0,
  123. /**
  124. *
  125. * @type {object}
  126. */
  127. checksUpdateStatus: null,
  128. /**
  129. *
  130. * @method navigateStep
  131. */
  132. navigateStep: function () {
  133. if (this.get('isLoaded')) {
  134. if (!this.get('content.installOptions.manualInstall')) {
  135. if (!this.get('wizardController').getDBProperty('bootStatus')) {
  136. this.startBootstrap();
  137. }
  138. } else {
  139. this.set('bootHosts', this.get('hosts'));
  140. if (App.get('testMode')) {
  141. this.startHostcheck();
  142. this.get('bootHosts').setEach('cpu', '2');
  143. this.get('bootHosts').setEach('memory', '2000000');
  144. this.set('isSubmitDisabled', false);
  145. } else {
  146. this.set('registrationStartedAt', null);
  147. this.startRegistration();
  148. }
  149. }
  150. }
  151. }.observes('isLoaded'),
  152. /**
  153. * Clear controller data
  154. * @method clearStep
  155. */
  156. clearStep: function () {
  157. this.set('stopBootstrap', false);
  158. this.set('hosts', []);
  159. this.get('bootHosts').clear();
  160. this.get('wizardController').setDBProperty('bootStatus', false);
  161. this.set('isSubmitDisabled', true);
  162. this.set('isRetryDisabled', true);
  163. },
  164. /**
  165. * Make basic init steps
  166. * @method loadStep
  167. */
  168. loadStep: function () {
  169. console.log("TRACE: Loading step3: Confirm Hosts");
  170. this.set('registrationStartedAt', null);
  171. this.set('isLoaded', false);
  172. this.disablePreviousSteps();
  173. this.clearStep();
  174. App.router.get('clusterController').loadAmbariProperties();
  175. this.loadHosts();
  176. },
  177. /**
  178. * Loads the hostinfo from localStorage on the insertion of view. It's being called from view
  179. * @method loadHosts
  180. */
  181. loadHosts: function () {
  182. var hostsInfo = this.get('content.hosts');
  183. var hosts = [];
  184. var bootStatus = (this.get('content.installOptions.manualInstall')) ? 'DONE' : 'PENDING';
  185. if (App.testMode) {
  186. bootStatus = 'REGISTERED';
  187. }
  188. for (var index in hostsInfo) {
  189. if (hostsInfo.hasOwnProperty(index)) {
  190. hosts.pushObject(App.HostInfo.create({
  191. name: hostsInfo[index].name,
  192. bootStatus: bootStatus,
  193. isChecked: false
  194. }));
  195. }
  196. }
  197. this.set('hosts', hosts);
  198. this.set('isLoaded', true);
  199. },
  200. /**
  201. * Parses and updates the content based on bootstrap API response.
  202. * @return {bool} true if polling should continue (some hosts are in "RUNNING" state); false otherwise
  203. * @method parseHostInfo
  204. */
  205. parseHostInfo: function (hostsStatusFromServer) {
  206. hostsStatusFromServer.forEach(function (_hostStatus) {
  207. var host = this.get('bootHosts').findProperty('name', _hostStatus.hostName);
  208. // check if hostname extracted from REST API data matches any hostname in content
  209. // also, make sure that bootStatus modified by isHostsRegistered call does not get overwritten
  210. // since these calls are being made in parallel
  211. if (host && !['REGISTERED', 'REGISTERING'].contains(host.get('bootStatus'))) {
  212. host.set('bootStatus', _hostStatus.status);
  213. host.set('bootLog', _hostStatus.log);
  214. }
  215. }, this);
  216. // if the data rendered by REST API has hosts in "RUNNING" state, polling will continue
  217. return this.get('bootHosts').length != 0 && this.get('bootHosts').someProperty('bootStatus', 'RUNNING');
  218. },
  219. /**
  220. * Remove list of hosts
  221. * @param {Ember.Enumerable} hosts
  222. * @return {App.ModalPopup}
  223. * @method removeHosts
  224. */
  225. removeHosts: function (hosts) {
  226. var self = this;
  227. return App.showConfirmationPopup(function () {
  228. App.router.send('removeHosts', hosts);
  229. self.hosts.removeObjects(hosts);
  230. if (!self.hosts.length) {
  231. self.set('isSubmitDisabled', true);
  232. }
  233. }, Em.I18n.t('installer.step3.hosts.remove.popup.body'));
  234. },
  235. /**
  236. * Removes a single element on the trash icon click. Called from View
  237. * @param {object} hostInfo
  238. * @method removeHost
  239. */
  240. removeHost: function (hostInfo) {
  241. this.removeHosts([hostInfo]);
  242. },
  243. /**
  244. * Remove selected hosts (click-handler)
  245. * @return App.ModalPopup
  246. * @method removeSelectedHosts
  247. */
  248. removeSelectedHosts: function () {
  249. var selectedHosts = this.get('hosts').filterProperty('isChecked', true);
  250. selectedHosts.forEach(function (_hostInfo) {
  251. console.log('Removing: ' + _hostInfo.name);
  252. });
  253. return this.removeHosts(selectedHosts);
  254. },
  255. /**
  256. * Show popup with the list of hosts which are selected
  257. * @return App.ModalPopup
  258. * @method selectedHostsPopup
  259. */
  260. selectedHostsPopup: function () {
  261. var selectedHosts = this.get('hosts').filterProperty('isChecked').mapProperty('name');
  262. return App.ModalPopup.show({
  263. header: Em.I18n.t('installer.step3.selectedHosts.popup.header'),
  264. secondary: null,
  265. bodyClass: Em.View.extend({
  266. templateName: require('templates/common/items_list_popup'),
  267. items: selectedHosts,
  268. insertedItems: [],
  269. didInsertElement: function () {
  270. lazyloading.run({
  271. destination: this.get('insertedItems'),
  272. source: this.get('items'),
  273. context: this,
  274. initSize: 100,
  275. chunkSize: 500,
  276. delay: 100
  277. });
  278. }
  279. })
  280. });
  281. },
  282. /**
  283. * Retry one host {click-handler}
  284. * @param {object} hostInfo
  285. * @method retryHost
  286. */
  287. retryHost: function (hostInfo) {
  288. this.retryHosts([hostInfo]);
  289. },
  290. /**
  291. * Retry list of hosts
  292. * @param {object[]} hosts
  293. * @method retryHosts
  294. */
  295. retryHosts: function (hosts) {
  296. var self = this;
  297. var bootStrapData = JSON.stringify({
  298. 'verbose': true,
  299. 'sshKey': this.get('content.installOptions.sshKey'),
  300. 'hosts': hosts.mapProperty('name'),
  301. 'user': this.get('content.installOptions.sshUser')}
  302. );
  303. this.set('numPolls', 0);
  304. this.set('registrationStartedAt', null);
  305. if (this.get('content.installOptions.manualInstall')) {
  306. this.get('bootHosts').setEach('bootStatus', 'DONE');
  307. this.startRegistration();
  308. }
  309. else {
  310. App.router.get(this.get('content.controllerName')).launchBootstrap(bootStrapData, function (requestId) {
  311. self.set('content.installOptions.bootRequestId', requestId);
  312. self.doBootstrap();
  313. });
  314. }
  315. },
  316. /**
  317. * Retry selected hosts (click-handler)
  318. * @method retrySelectedHosts
  319. */
  320. retrySelectedHosts: function () {
  321. if (!this.get('isRetryDisabled')) {
  322. this.set('isRetryDisabled', true);
  323. var selectedHosts = this.get('bootHosts').filterProperty('bootStatus', 'FAILED');
  324. selectedHosts.forEach(function (_host) {
  325. _host.set('bootStatus', 'RUNNING');
  326. _host.set('bootLog', 'Retrying ...');
  327. }, this);
  328. this.retryHosts(selectedHosts);
  329. }
  330. },
  331. /**
  332. * Init bootstrap settings and start it
  333. * @method startBootstrap
  334. */
  335. startBootstrap: function () {
  336. //this.set('isSubmitDisabled', true); //TODO: uncomment after actual hookup
  337. this.set('numPolls', 0);
  338. this.set('registrationStartedAt', null);
  339. this.set('bootHosts', this.get('hosts'));
  340. this.doBootstrap();
  341. },
  342. /**
  343. * Update <code>isRegistrationInProgress</code> once
  344. * @method setRegistrationInProgressOnce
  345. */
  346. setRegistrationInProgressOnce: function () {
  347. Em.run.once(this, 'setRegistrationInProgress');
  348. }.observes('bootHosts.@each.bootStatus'),
  349. /**
  350. * Set <code>isRegistrationInProgress</code> value based on each host boot status
  351. * @method setRegistrationInProgress
  352. */
  353. setRegistrationInProgress: function () {
  354. var bootHosts = this.get('bootHosts');
  355. //if hosts aren't loaded yet then registration should be in progress
  356. var result = (bootHosts.length === 0 && !this.get('isLoaded'));
  357. for (var i = 0, l = bootHosts.length; i < l; i++) {
  358. if (bootHosts[i].get('bootStatus') !== 'REGISTERED' && bootHosts[i].get('bootStatus') !== 'FAILED') {
  359. result = true;
  360. break;
  361. }
  362. }
  363. this.set('isRegistrationInProgress', result);
  364. },
  365. /**
  366. * Disable wizard's previous steps (while registering)
  367. * @method disablePreviousSteps
  368. */
  369. disablePreviousSteps: function () {
  370. App.router.get('installerController.isStepDisabled').filter(function (step) {
  371. return step.step >= 0 && step.step <= 2;
  372. }).setEach('value', this.get('isRegistrationInProgress'));
  373. if (this.get('isRegistrationInProgress')) {
  374. this.set('isSubmitDisabled', true);
  375. }
  376. }.observes('isRegistrationInProgress'),
  377. /**
  378. * Do bootstrap calls
  379. * @method doBootstrap
  380. * @return {$.ajax|null}
  381. */
  382. doBootstrap: function () {
  383. if (this.get('stopBootstrap')) {
  384. return null;
  385. }
  386. this.incrementProperty('numPolls');
  387. return App.ajax.send({
  388. name: 'wizard.step3.bootstrap',
  389. sender: this,
  390. data: {
  391. bootRequestId: this.get('content.installOptions.bootRequestId'),
  392. numPolls: this.get('numPolls')
  393. },
  394. success: 'doBootstrapSuccessCallback'
  395. }).
  396. retry({
  397. times: App.maxRetries,
  398. timeout: App.timeout
  399. }).
  400. then(
  401. null,
  402. function () {
  403. App.showReloadPopup();
  404. console.log('Bootstrap failed');
  405. }
  406. );
  407. },
  408. /**
  409. * Success-callback for each boostrap request
  410. * @param {object} data
  411. * @method doBootstrapSuccessCallback
  412. */
  413. doBootstrapSuccessCallback: function (data) {
  414. var self = this;
  415. var pollingInterval = 3000;
  416. if (Em.isNone(data.hostsStatus)) {
  417. console.log('Invalid response, setting timeout');
  418. window.setTimeout(function () {
  419. self.doBootstrap()
  420. }, pollingInterval);
  421. } else {
  422. // in case of bootstrapping just one host, the server returns an object rather than an array, so
  423. // force into an array
  424. if (!(data.hostsStatus instanceof Array)) {
  425. data.hostsStatus = [ data.hostsStatus ];
  426. }
  427. console.log("TRACE: In success function for the GET bootstrap call");
  428. var keepPolling = this.parseHostInfo(data.hostsStatus);
  429. // Single host : if the only hostname is invalid (data.status == 'ERROR')
  430. // Multiple hosts : if one or more hostnames are invalid
  431. // following check will mark the bootStatus as 'FAILED' for the invalid hostname
  432. if (data.status == 'ERROR' || data.hostsStatus.length != this.get('bootHosts').length) {
  433. var hosts = this.get('bootHosts');
  434. for (var i = 0; i < hosts.length; i++) {
  435. var isValidHost = data.hostsStatus.someProperty('hostName', hosts[i].get('name'));
  436. if (hosts[i].get('bootStatus') !== 'REGISTERED') {
  437. if (!isValidHost) {
  438. hosts[i].set('bootStatus', 'FAILED');
  439. hosts[i].set('bootLog', Em.I18n.t('installer.step3.hosts.bootLog.failed'));
  440. }
  441. }
  442. }
  443. }
  444. if (data.status == 'ERROR' || data.hostsStatus.someProperty('status', 'DONE') || data.hostsStatus.someProperty('status', 'FAILED')) {
  445. // kicking off registration polls after at least one host has succeeded
  446. this.startRegistration();
  447. }
  448. if (keepPolling) {
  449. window.setTimeout(function () {
  450. self.doBootstrap()
  451. }, pollingInterval);
  452. }
  453. }
  454. },
  455. /**
  456. * Start hosts registration
  457. * @method startRegistration
  458. */
  459. startRegistration: function () {
  460. if (Em.isNone(this.get('registrationStartedAt'))) {
  461. this.set('registrationStartedAt', App.dateTime());
  462. console.log('registration started at ' + this.get('registrationStartedAt'));
  463. this.isHostsRegistered();
  464. }
  465. },
  466. /**
  467. * Do requests to check if hosts are already registered
  468. * @return {$.ajax|null}
  469. * @method isHostsRegistered
  470. */
  471. isHostsRegistered: function () {
  472. if (this.get('stopBootstrap')) {
  473. return null;
  474. }
  475. return App.ajax.send({
  476. name: 'wizard.step3.is_hosts_registered',
  477. sender: this,
  478. success: 'isHostsRegisteredSuccessCallback'
  479. }).
  480. retry({
  481. times: App.maxRetries,
  482. timeout: App.timeout
  483. }).
  484. then(
  485. null,
  486. function () {
  487. App.showReloadPopup();
  488. console.log('Error: Getting registered host information from the server');
  489. }
  490. );
  491. },
  492. /**
  493. * Success-callback for registered hosts request
  494. * @param {object} data
  495. * @method isHostsRegisteredSuccessCallback
  496. */
  497. isHostsRegisteredSuccessCallback: function (data) {
  498. console.log('registration attempt...');
  499. var hosts = this.get('bootHosts');
  500. var jsonData = data;
  501. if (!jsonData) {
  502. console.warn("Error: jsonData is null");
  503. return;
  504. }
  505. // keep polling until all hosts have registered/failed, or registrationTimeout seconds after the last host finished bootstrapping
  506. var stopPolling = true;
  507. hosts.forEach(function (_host, index) {
  508. // Change name of first host for test mode.
  509. if (App.testMode) {
  510. if (index == 0) {
  511. _host.set('name', 'localhost.localdomain');
  512. }
  513. }
  514. // actions to take depending on the host's current bootStatus
  515. // RUNNING - bootstrap is running; leave it alone
  516. // DONE - bootstrap is done; transition to REGISTERING
  517. // REGISTERING - bootstrap is done but has not registered; transition to REGISTERED if host found in polling API result
  518. // REGISTERED - bootstrap and registration is done; leave it alone
  519. // FAILED - either bootstrap or registration failed; leave it alone
  520. switch (_host.get('bootStatus')) {
  521. case 'DONE':
  522. _host.set('bootStatus', 'REGISTERING');
  523. _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + Em.I18n.t('installer.step3.hosts.bootLog.registering'));
  524. // update registration timestamp so that the timeout is computed from the last host that finished bootstrapping
  525. this.set('registrationStartedAt', App.dateTime());
  526. stopPolling = false;
  527. break;
  528. case 'REGISTERING':
  529. if (jsonData.items.someProperty('Hosts.host_name', _host.name)) {
  530. _host.set('bootStatus', 'REGISTERED');
  531. _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + Em.I18n.t('installer.step3.hosts.bootLog.registering'));
  532. } else {
  533. stopPolling = false;
  534. }
  535. break;
  536. case 'RUNNING':
  537. stopPolling = false;
  538. break;
  539. case 'REGISTERED':
  540. case 'FAILED':
  541. default:
  542. break;
  543. }
  544. }, this);
  545. if (stopPolling) {
  546. this.startHostcheck();
  547. }
  548. else {
  549. if (hosts.someProperty('bootStatus', 'RUNNING') || App.dateTime() - this.get('registrationStartedAt') < this.get('registrationTimeoutSecs') * 1000) {
  550. // we want to keep polling for registration status if any of the hosts are still bootstrapping (so we check for RUNNING).
  551. var self = this;
  552. window.setTimeout(function () {
  553. self.isHostsRegistered();
  554. }, 3000);
  555. }
  556. else {
  557. // registration timed out. mark all REGISTERING hosts to FAILED
  558. console.log('registration timed out');
  559. hosts.filterProperty('bootStatus', 'REGISTERING').forEach(function (_host) {
  560. _host.set('bootStatus', 'FAILED');
  561. _host.set('bootLog', (_host.get('bootLog') != null ? _host.get('bootLog') : '') + Em.I18n.t('installer.step3.hosts.bootLog.failed'));
  562. });
  563. this.startHostcheck();
  564. }
  565. }
  566. },
  567. /**
  568. * Do request for all registered hosts
  569. * @return {$.ajax}
  570. * @method getAllRegisteredHosts
  571. */
  572. getAllRegisteredHosts: function () {
  573. return App.ajax.send({
  574. name: 'wizard.step3.is_hosts_registered',
  575. sender: this,
  576. success: 'getAllRegisteredHostsCallback'
  577. });
  578. }.observes('bootHosts'),
  579. /**
  580. * Success-callback for all registered hosts request
  581. * @param {object} hosts
  582. * @method getAllRegisteredHostsCallback
  583. */
  584. getAllRegisteredHostsCallback: function (hosts) {
  585. var registeredHosts = [];
  586. var hostsInCluster = this.get('hostsInCluster');
  587. var addedHosts = this.get('bootHosts').getEach('name');
  588. hosts.items.forEach(function (host) {
  589. if (!hostsInCluster.contains(host.Hosts.host_name) && !addedHosts.contains(host.Hosts.host_name)) {
  590. registeredHosts.push(host.Hosts.host_name);
  591. }
  592. });
  593. if (registeredHosts.length) {
  594. this.set('hasMoreRegisteredHosts', true);
  595. this.set('registeredHosts', registeredHosts);
  596. } else {
  597. this.set('hasMoreRegisteredHosts', false);
  598. this.set('registeredHosts', '');
  599. }
  600. },
  601. /**
  602. * Show popup with regitration error-message
  603. * @param {string} header
  604. * @param {string} message
  605. * @return {App.ModalPopup}
  606. * @method registerErrPopup
  607. */
  608. registerErrPopup: function (header, message) {
  609. return App.ModalPopup.show({
  610. header: header,
  611. secondary: false,
  612. bodyClass: Em.View.extend({
  613. template: Em.Handlebars.compile('<p>{{view.message}}</p>'),
  614. message: message
  615. })
  616. });
  617. },
  618. /**
  619. * Get JDK name from server to determine if user had setup a customized JDK path when doing 'ambari-server setup'.
  620. * The Ambari properties are different from default ambari-server setup, property 'jdk.name' will be missing if a customized jdk path is applied.
  621. * @return {$.ajax}
  622. * @method getJDKName
  623. */
  624. getJDKName: function () {
  625. return App.ajax.send({
  626. name: 'ambari.service.load_jdk_name',
  627. sender: this,
  628. success: 'getJDKNameSuccessCallback'
  629. });
  630. },
  631. /**
  632. * Success callback for JDK name, property 'jdk.name' will be missing if a customized jdk path is applied
  633. * @param {object} data
  634. * @method getJDKNameSuccessCallback
  635. */
  636. getJDKNameSuccessCallback: function (data) {
  637. this.set('needJDKCheckOnHosts', !data.RootServiceComponents.properties["jdk.name"]);
  638. this.set('jdkLocation', Em.get(data, "RootServiceComponents.properties.jdk_location"));
  639. this.set('javaHome', data.RootServiceComponents.properties["java.home"]);
  640. },
  641. doCheckJDK: function () {
  642. var hostsNames = this.get('bootHosts').getEach('name').join(",");
  643. var javaHome = this.get('javaHome');
  644. var jdkLocation = this.get('jdkLocation');
  645. App.ajax.send({
  646. name: 'wizard.step3.jdk_check',
  647. sender: this,
  648. data: {
  649. host_names: hostsNames,
  650. java_home: javaHome,
  651. jdk_location: jdkLocation
  652. },
  653. success: 'doCheckJDKsuccessCallback',
  654. error: 'doCheckJDKerrorCallback'
  655. });
  656. },
  657. doCheckJDKsuccessCallback: function (data) {
  658. var requestIndex = data.href.split('/')[data.href.split('/').length - 1];
  659. var self = this;
  660. // keep getting JDK check results data until all hosts jdk check completed
  661. var myVar = setInterval( function(){
  662. if (self.get('jdkCategoryWarnings') == null) {
  663. // get jdk check results for all hosts
  664. App.ajax.send({
  665. name: 'wizard.step3.jdk_check.get_results',
  666. sender: self,
  667. data: {
  668. requestIndex: requestIndex
  669. },
  670. success: 'parseJDKCheckResults'
  671. })
  672. } else {
  673. clearInterval(myVar);
  674. self.set('isJDKWarningsLoaded', true);
  675. }
  676. },
  677. 1000);
  678. },
  679. doCheckJDKerrorCallback: function () {
  680. console.log('INFO: Doing JDK check for host failed');
  681. this.set('isJDKWarningsLoaded', true);
  682. },
  683. parseJDKCheckResults: function (data) {
  684. var jdkWarnings = [], hostsJDKContext = [], hostsJDKNames = [];
  685. // check if the request ended
  686. if (data.Requests.end_time > 0 && data.tasks) {
  687. data.tasks.forEach( function(task) {
  688. // generate warning context
  689. if (Em.get(task, "Tasks.structured_out.java_home_check.exit_code") == 1){
  690. var jdkContext = Em.I18n.t('installer.step3.hostWarningsPopup.jdk.context').format(task.Tasks.host_name);
  691. hostsJDKContext.push(jdkContext);
  692. hostsJDKNames.push(task.Tasks.host_name);
  693. }
  694. });
  695. if (hostsJDKContext.length > 0) { // java jdk warning exist
  696. var invalidJavaHome = this.get('javaHome');
  697. jdkWarnings.push({
  698. name: Em.I18n.t('installer.step3.hostWarningsPopup.jdk.name').format(invalidJavaHome),
  699. hosts: hostsJDKContext,
  700. hostsNames: hostsJDKNames,
  701. category: 'jdk',
  702. onSingleHost: false
  703. });
  704. }
  705. this.set('jdkCategoryWarnings', jdkWarnings);
  706. } else {
  707. // still doing JDK check, data not ready to be parsed
  708. this.set('jdkCategoryWarnings', null);
  709. }
  710. },
  711. /**
  712. * Check JDK issues on registered hosts.
  713. */
  714. checkHostJDK: function () {
  715. this.set('isJDKWarningsLoaded', false);
  716. this.set('jdkCategoryWarnings', null);
  717. var self = this;
  718. this.getJDKName().done( function() {
  719. if (self.get('needJDKCheckOnHosts')) {
  720. // need to do JDK check on each host
  721. self.doCheckJDK();
  722. } else {
  723. // no customized JDK path, so no need to check jdk
  724. self.set('jdkCategoryWarnings', []);
  725. self.set('isJDKWarningsLoaded', true);
  726. }
  727. });
  728. },
  729. /**
  730. * Get disk info and cpu count of booted hosts from server
  731. * @return {$.ajax}
  732. * @method getHostInfo
  733. */
  734. getHostInfo: function () {
  735. this.set('isHostsWarningsLoaded', false);
  736. // begin JDK check for each host
  737. return App.ajax.send({
  738. name: 'wizard.step3.host_info',
  739. sender: this,
  740. success: 'getHostInfoSuccessCallback',
  741. error: 'getHostInfoErrorCallback'
  742. });
  743. },
  744. startHostcheck: function() {
  745. this.set('isWarningsLoaded', false);
  746. this.getHostNameResolution();
  747. this.checkHostJDK();
  748. },
  749. getHostNameResolution: function () {
  750. var hosts = this.get('bootHosts').getEach('name').join(",");
  751. var jdk_location = App.router.get('clusterController.ambariProperties.jdk_location');
  752. var RequestInfo = {
  753. "action": "check_host",
  754. "context": "Check host",
  755. "parameters": {
  756. "check_execute_list": "host_resolution_check",
  757. "jdk_location" : jdk_location,
  758. "hosts": hosts,
  759. "threshold": "20"
  760. }
  761. };
  762. var resource_filters = {
  763. "hosts": hosts
  764. };
  765. if (App.testMode) {
  766. this.getHostNameResolutionSuccess();
  767. } else {
  768. return App.ajax.send({
  769. name: 'preinstalled.checks',
  770. sender: this,
  771. data: {
  772. RequestInfo: RequestInfo,
  773. resource_filters: resource_filters
  774. },
  775. success: 'getHostNameResolutionSuccess',
  776. error: 'getHostNameResolutionError'
  777. });
  778. }
  779. },
  780. getHostNameResolutionSuccess: function(response) {
  781. if (!App.testMode) {
  782. this.set("requestId", response.Requests.id);
  783. }
  784. this.getHostCheckTasks();
  785. },
  786. getHostNameResolutionError: function() {
  787. this.getHostInfo();
  788. },
  789. /**
  790. * send ajax request to get all tasks
  791. * @method getHostCheckTasks
  792. */
  793. getHostCheckTasks: function () {
  794. var requestId = this.get("requestId");
  795. var self = this;
  796. var checker = setInterval(function () {
  797. if (self.get('stopChecking') == true) {
  798. clearInterval(checker);
  799. self.getHostInfo();
  800. } else {
  801. App.ajax.send({
  802. name: 'preinstalled.checks.tasks',
  803. sender: self,
  804. data: {
  805. requestId: requestId
  806. },
  807. success: 'getHostCheckTasksSuccess',
  808. error: 'getHostCheckTasksError'
  809. });
  810. }
  811. }, 1000);
  812. },
  813. /**
  814. * add warnings to host warning popup if needed
  815. * @param data {Object} - json
  816. * @method getHostCheckTasksSuccess
  817. */
  818. getHostCheckTasksSuccess: function (data) {
  819. console.log('checking attempt...');
  820. if (!data) {
  821. console.warn("Error: jsonData is null");
  822. return;
  823. }
  824. this.set('stopChecking', true);
  825. data.tasks.forEach(function (task) {
  826. var name = Em.I18n.t('installer.step3.hostWarningsPopup.resolution.validation.error');
  827. var hostInfo = this.get("hostCheckWarnings").findProperty('name', name);
  828. if (task.Tasks.status == "FAILED" || task.Tasks.status == "COMPLETED" || task.Tasks.status == "TIMEDOUT") {
  829. if (task.Tasks.status == "COMPLETED") {
  830. if (Em.get(task, "Tasks.structured_out.host_resolution_check.failed_count") == 0) {
  831. return;
  832. }
  833. }
  834. if (!hostInfo) {
  835. hostInfo = {
  836. name: name,
  837. hosts: [task.Tasks.host_name],
  838. onSingleHost: true
  839. };
  840. this.get("hostCheckWarnings").push(hostInfo);
  841. } else {
  842. if (!hostInfo.hosts.contains(task.Tasks.host_name)) {
  843. hostInfo.hosts.push(task.Tasks.host_name);
  844. }
  845. }
  846. } else {
  847. this.set('stopChecking', false);
  848. }
  849. }, this);
  850. },
  851. stopChecking: false,
  852. /**
  853. * @method getHostCheckTasksError
  854. */
  855. getHostCheckTasksError: function() {
  856. console.warn("failed to cheek hostName resolution");
  857. this.set('stopChecking', true);
  858. },
  859. /**
  860. * Success-callback for hosts info request
  861. * @param {object} jsonData
  862. * @method getHostInfoSuccessCallback
  863. */
  864. getHostInfoSuccessCallback: function (jsonData) {
  865. var hosts = this.get('bootHosts'),
  866. self = this,
  867. repoWarnings = [], hostsRepoNames = [], hostsContext = [],
  868. diskWarnings = [], hostsDiskContext = [], hostsDiskNames = [];
  869. // parse host checks warning
  870. this.parseWarnings(jsonData);
  871. hosts.forEach(function (_host) {
  872. var host = (App.get('testMode')) ? jsonData.items[0] : jsonData.items.findProperty('Hosts.host_name', _host.name);
  873. if (App.get('skipBootstrap')) {
  874. self._setHostDataWithSkipBootstrap(_host);
  875. }
  876. else {
  877. if (host) {
  878. self._setHostDataFromLoadedHostInfo(_host, host);
  879. var host_name = Em.get(host, 'Hosts.host_name');
  880. var context = self.checkHostOSType(host.Hosts.os_type, host_name);
  881. if (context) {
  882. hostsContext.push(context);
  883. hostsRepoNames.push(host_name);
  884. }
  885. var diskContext = self.checkHostDiskSpace(host_name, host.Hosts.disk_info);
  886. if (diskContext) {
  887. hostsDiskContext.push(diskContext);
  888. hostsDiskNames.push(host_name);
  889. }
  890. }
  891. }
  892. });
  893. if (hostsContext.length > 0) { // repository warning exist
  894. repoWarnings.push({
  895. name: Em.I18n.t('installer.step3.hostWarningsPopup.repositories.name'),
  896. hosts: hostsContext,
  897. hostsNames: hostsRepoNames,
  898. category: 'repositories',
  899. onSingleHost: false
  900. });
  901. }
  902. if (hostsDiskContext.length > 0) { // disk space warning exist
  903. diskWarnings.push({
  904. name: Em.I18n.t('installer.step3.hostWarningsPopup.disk.name'),
  905. hosts: hostsDiskContext,
  906. hostsNames: hostsDiskNames,
  907. category: 'disk',
  908. onSingleHost: false
  909. });
  910. }
  911. this.set('repoCategoryWarnings', repoWarnings);
  912. this.set('diskCategoryWarnings', diskWarnings);
  913. this.stopRegistration();
  914. },
  915. /**
  916. * Set metrics to host object
  917. * Used when <code>App.skipBootstrap</code> is true
  918. * @param {Ember.Object} host
  919. * @returns {object}
  920. * @private
  921. * @methos _setHostDataWithSkipBootstrap
  922. */
  923. _setHostDataWithSkipBootstrap: function(host) {
  924. host.set('cpu', 2);
  925. host.set('memory', ((parseInt(2000000))).toFixed(2));
  926. host.set('disk_info', [
  927. {"mountpoint": "/", "type": "ext4"},
  928. {"mountpoint": "/grid/0", "type": "ext4"},
  929. {"mountpoint": "/grid/1", "type": "ext4"},
  930. {"mountpoint": "/grid/2", "type": "ext4"}
  931. ]);
  932. return host;
  933. },
  934. /**
  935. * Set loaded metrics to host object
  936. * @param {object} host
  937. * @param {object} hostInfo
  938. * @returns {object}
  939. * @method _setHostDataFromLoadedHostInfo
  940. * @private
  941. */
  942. _setHostDataFromLoadedHostInfo: function(host, hostInfo) {
  943. host.set('cpu', Em.get(hostInfo, 'Hosts.cpu_count'));
  944. host.set('memory', ((parseInt(Em.get(hostInfo, 'Hosts.total_mem')))).toFixed(2));
  945. host.set('disk_info', Em.get(hostInfo, 'Hosts.disk_info').filter(function (h) {
  946. return h.mountpoint != "/boot"
  947. }));
  948. host.set('os_type', Em.get(hostInfo, 'Hosts.os_type'));
  949. host.set('os_arch', Em.get(hostInfo, 'Hosts.os_arch'));
  950. host.set('ip', Em.get(hostInfo, 'Hosts.ip'));
  951. return host;
  952. },
  953. /**
  954. * Error-callback for hosts info request
  955. * @method getHostInfoErrorCallback
  956. */
  957. getHostInfoErrorCallback: function () {
  958. console.log('INFO: Getting host information(cpu_count and total_mem) from the server failed');
  959. this.set('isHostsWarningsLoaded', true);
  960. this.registerErrPopup(Em.I18n.t('installer.step3.hostInformation.popup.header'), Em.I18n.t('installer.step3.hostInformation.popup.body'));
  961. },
  962. /**
  963. * Enable or disable submit/retry buttons according to hosts boot statuses
  964. * @method stopRegistration
  965. */
  966. stopRegistration: function () {
  967. this.set('isSubmitDisabled', !this.get('bootHosts').someProperty('bootStatus', 'REGISTERED'));
  968. this.set('isRetryDisabled', !this.get('bootHosts').someProperty('bootStatus', 'FAILED'));
  969. },
  970. /**
  971. * Check if the customized os group contains the registered host os type. If not the repo on that host is invalid.
  972. * @param {string} osType
  973. * @param {string} hostName
  974. * @return {string} error-message or empty string
  975. * @method checkHostOSType
  976. */
  977. checkHostOSType: function (osType, hostName) {
  978. if (this.get('content.stacks')) {
  979. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  980. var selectedOS = [];
  981. var self = this;
  982. var isValid = false;
  983. if (selectedStack && selectedStack.operatingSystems) {
  984. selectedStack.get('operatingSystems').filterProperty('selected', true).forEach(function (os) {
  985. selectedOS.pushObject(os.osType);
  986. if (self.repoToAgentOsType(os.osType).indexOf(osType) >= 0) {
  987. isValid = true;
  988. }
  989. });
  990. }
  991. if (isValid) {
  992. return '';
  993. } else {
  994. console.log('WARNING: Getting host os type does NOT match the user selected os group in step1. ' +
  995. 'Host Name: ' + hostName + '. Host os type:' + osType + '. Selected group:' + selectedOS.uniq());
  996. return Em.I18n.t('installer.step3.hostWarningsPopup.repositories.context').format(hostName, osType, selectedOS.uniq());
  997. }
  998. } else {
  999. return '';
  1000. }
  1001. },
  1002. /**
  1003. * return the supported agent os types for a repo os type
  1004. * @param {String} repoType
  1005. * @return {Array} supported agent os type array
  1006. * @method repoToAgentOsType
  1007. */
  1008. repoToAgentOsType : function (repoType) {
  1009. switch (repoType) {
  1010. case "redhat6":
  1011. return ["redhat6", "centos6", "oraclelinux6", "rhel6"];
  1012. case "redhat5":
  1013. return ["redhat5", "centos5", "oraclelinux5", "rhel5"];
  1014. case "suse11":
  1015. return ["suse11", "sles11", "opensuse11"];
  1016. case "debian12":
  1017. return ["debian12", "ubuntu12"];
  1018. default:
  1019. return [];
  1020. }
  1021. },
  1022. /**
  1023. * Check if current host has enough free disk usage.
  1024. * @param {string} hostName
  1025. * @param {object} diskInfo
  1026. * @return {string} error-message or empty string
  1027. * @method checkHostDiskSpace
  1028. */
  1029. checkHostDiskSpace: function (hostName, diskInfo) {
  1030. var minFreeRootSpace = App.minDiskSpace * 1024 * 1024; //in kilobyte
  1031. var minFreeUsrLibSpace = App.minDiskSpaceUsrLib * 1024 * 1024; //in kilobyte
  1032. var warningString = '';
  1033. diskInfo.forEach(function (info) {
  1034. switch (info.mountpoint) {
  1035. case '/':
  1036. warningString = info.available < minFreeRootSpace ?
  1037. Em.I18n.t('installer.step3.hostWarningsPopup.disk.context2').format(App.minDiskSpace + 'GB', info.mountpoint) + ' ' + warningString :
  1038. warningString;
  1039. break;
  1040. case '/usr':
  1041. case '/usr/lib':
  1042. warningString = info.available < minFreeUsrLibSpace ?
  1043. Em.I18n.t('installer.step3.hostWarningsPopup.disk.context2').format(App.minDiskSpaceUsrLib + 'GB', info.mountpoint) + ' ' + warningString :
  1044. warningString;
  1045. break;
  1046. default:
  1047. break;
  1048. }
  1049. });
  1050. if (warningString) {
  1051. console.log('WARNING: Getting host free disk space. ' + 'Host Name: ' + hostName);
  1052. return Em.I18n.t('installer.step3.hostWarningsPopup.disk.context1').format(hostName) + ' ' + warningString;
  1053. } else {
  1054. return '';
  1055. }
  1056. },
  1057. /**
  1058. * Submit-click handler
  1059. * @return {App.ModalPopup|null}
  1060. * @method submit
  1061. */
  1062. submit: function () {
  1063. if (this.get('isHostHaveWarnings')) {
  1064. var self = this;
  1065. return App.showConfirmationPopup(
  1066. function () {
  1067. self.set('content.hosts', self.get('bootHosts'));
  1068. App.router.send('next');
  1069. },
  1070. Em.I18n.t('installer.step3.hostWarningsPopup.hostHasWarnings'));
  1071. }
  1072. else {
  1073. this.set('content.hosts', this.get('bootHosts'));
  1074. App.router.send('next');
  1075. }
  1076. return null;
  1077. },
  1078. /**
  1079. * Show popup with host log
  1080. * @param {object} event
  1081. * @return {App.ModalPopup}
  1082. */
  1083. hostLogPopup: function (event) {
  1084. var host = event.context;
  1085. return App.ModalPopup.show({
  1086. header: Em.I18n.t('installer.step3.hostLog.popup.header').format(host.get('name')),
  1087. secondary: null,
  1088. host: host,
  1089. bodyClass: App.WizardStep3HostLogPopupBody
  1090. });
  1091. },
  1092. /**
  1093. * Check warnings from server and put it in parsing
  1094. * @method rerunChecks
  1095. */
  1096. rerunChecks: function () {
  1097. var self = this;
  1098. var currentProgress = 0;
  1099. this.getHostNameResolution();
  1100. this.checkHostJDK();
  1101. var interval = setInterval(function () {
  1102. currentProgress += 100000 / self.get('warningsTimeInterval');
  1103. if (currentProgress < 100) {
  1104. self.set('checksUpdateProgress', currentProgress);
  1105. } else {
  1106. clearInterval(interval);
  1107. App.ajax.send({
  1108. name: 'wizard.step3.rerun_checks',
  1109. sender: self,
  1110. success: 'rerunChecksSuccessCallback',
  1111. error: 'rerunChecksErrorCallback'
  1112. });
  1113. }
  1114. }, 1000);
  1115. },
  1116. /**
  1117. * Success-callback for rerun request
  1118. * @param {object} data
  1119. * @method rerunChecksSuccessCallback
  1120. */
  1121. rerunChecksSuccessCallback: function (data) {
  1122. this.set('checksUpdateProgress', 100);
  1123. this.set('checksUpdateStatus', 'SUCCESS');
  1124. this.parseWarnings(data);
  1125. },
  1126. /**
  1127. * Error-callback for rerun request
  1128. * @method rerunChecksErrorCallback
  1129. */
  1130. rerunChecksErrorCallback: function () {
  1131. this.set('checksUpdateProgress', 100);
  1132. this.set('checksUpdateStatus', 'FAILED');
  1133. console.log('INFO: Getting host information(last_agent_env) from the server failed');
  1134. },
  1135. /**
  1136. * Filter data for warnings parse
  1137. * is data from host in bootStrap
  1138. * @param {object} data
  1139. * @return {Object}
  1140. * @method filterBootHosts
  1141. */
  1142. filterBootHosts: function (data) {
  1143. var bootHostNames = {};
  1144. this.get('bootHosts').forEach(function (bootHost) {
  1145. bootHostNames[bootHost.get('name')] = true;
  1146. });
  1147. var filteredData = {
  1148. href: data.href,
  1149. items: []
  1150. };
  1151. data.items.forEach(function (host) {
  1152. if (bootHostNames[host.Hosts.host_name]) {
  1153. filteredData.items.push(host);
  1154. }
  1155. });
  1156. return filteredData;
  1157. },
  1158. /**
  1159. * Parse warnings data for each host and total
  1160. * @param {object} data
  1161. * @method parseWarnings
  1162. */
  1163. parseWarnings: function (data) {
  1164. data = App.testMode ? data : this.filterBootHosts(data);
  1165. var warnings = [];
  1166. var warning;
  1167. var hosts = [];
  1168. var warningCategories = {
  1169. fileFoldersWarnings: {},
  1170. packagesWarnings: {},
  1171. processesWarnings: {},
  1172. servicesWarnings: {},
  1173. usersWarnings: {},
  1174. alternativeWarnings: {}
  1175. };
  1176. data.items.sortPropertyLight('Hosts.host_name').forEach(function (_host) {
  1177. var host = {
  1178. name: _host.Hosts.host_name,
  1179. warnings: []
  1180. };
  1181. if (!_host.Hosts.last_agent_env) {
  1182. // in some unusual circumstances when last_agent_env is not available from the _host,
  1183. // skip the _host and proceed to process the rest of the hosts.
  1184. console.log("last_agent_env is missing for " + _host.Hosts.host_name + ". Skipping _host check.");
  1185. return;
  1186. }
  1187. //parse all directories and files warnings for host
  1188. //todo: to be removed after check in new API
  1189. var stackFoldersAndFiles = _host.Hosts.last_agent_env.stackFoldersAndFiles || [];
  1190. stackFoldersAndFiles.forEach(function (path) {
  1191. warning = warningCategories.fileFoldersWarnings[path.name];
  1192. if (warning) {
  1193. warning.hosts.push(_host.Hosts.host_name);
  1194. warning.onSingleHost = false;
  1195. } else {
  1196. warningCategories.fileFoldersWarnings[path.name] = warning = {
  1197. name: path.name,
  1198. hosts: [_host.Hosts.host_name],
  1199. category: 'fileFolders',
  1200. onSingleHost: true
  1201. };
  1202. }
  1203. host.warnings.push(warning);
  1204. }, this);
  1205. //parse all package warnings for host
  1206. if (_host.Hosts.last_agent_env.installedPackages) {
  1207. _host.Hosts.last_agent_env.installedPackages.forEach(function (_package) {
  1208. warning = warningCategories.packagesWarnings[_package.name];
  1209. if (warning) {
  1210. warning.hosts.push(_host.Hosts.host_name);
  1211. warning.version = _package.version;
  1212. warning.onSingleHost = false;
  1213. } else {
  1214. warningCategories.packagesWarnings[_package.name] = warning = {
  1215. name: _package.name,
  1216. version: _package.version,
  1217. hosts: [_host.Hosts.host_name],
  1218. category: 'packages',
  1219. onSingleHost: true
  1220. };
  1221. }
  1222. host.warnings.push(warning);
  1223. }, this);
  1224. }
  1225. //parse all process warnings for host
  1226. //todo: to be removed after check in new API
  1227. var javaProcs = _host.Hosts.last_agent_env.hostHealth ? _host.Hosts.last_agent_env.hostHealth.activeJavaProcs : _host.Hosts.last_agent_env.javaProcs;
  1228. if (javaProcs) {
  1229. javaProcs.forEach(function (process) {
  1230. warning = warningCategories.processesWarnings[process.pid];
  1231. if (warning) {
  1232. warning.hosts.push(_host.Hosts.host_name);
  1233. warning.onSingleHost = false;
  1234. } else {
  1235. warningCategories.processesWarnings[process.pid] = warning = {
  1236. name: (process.command.substr(0, 35) + '...'),
  1237. hosts: [_host.Hosts.host_name],
  1238. category: 'processes',
  1239. user: process.user,
  1240. pid: process.pid,
  1241. command: '<table><tr><td style="word-break: break-all;">' +
  1242. ((process.command.length < 500) ? process.command : process.command.substr(0, 230) + '...' +
  1243. '<p style="text-align: center">................</p>' +
  1244. '...' + process.command.substr(-230)) + '</td></tr></table>',
  1245. onSingleHost: true
  1246. };
  1247. }
  1248. host.warnings.push(warning);
  1249. }, this);
  1250. }
  1251. //parse all service warnings for host
  1252. //todo: to be removed after check in new API
  1253. if (_host.Hosts.last_agent_env.hostHealth && _host.Hosts.last_agent_env.hostHealth.liveServices) {
  1254. _host.Hosts.last_agent_env.hostHealth.liveServices.forEach(function (service) {
  1255. if (service.status === 'Unhealthy') {
  1256. warning = warningCategories.servicesWarnings[service.name];
  1257. if (warning) {
  1258. warning.hosts.push(_host.Hosts.host_name);
  1259. warning.onSingleHost = false;
  1260. } else {
  1261. warningCategories.servicesWarnings[service.name] = warning = {
  1262. name: service.name,
  1263. hosts: [_host.Hosts.host_name],
  1264. category: 'services',
  1265. onSingleHost: true
  1266. };
  1267. }
  1268. host.warnings.push(warning);
  1269. }
  1270. }, this);
  1271. }
  1272. //parse all user warnings for host
  1273. //todo: to be removed after check in new API
  1274. if (_host.Hosts.last_agent_env.existingUsers) {
  1275. _host.Hosts.last_agent_env.existingUsers.forEach(function (user) {
  1276. warning = warningCategories.usersWarnings[user.userName];
  1277. if (warning) {
  1278. warning.hosts.push(_host.Hosts.host_name);
  1279. warning.onSingleHost = false;
  1280. } else {
  1281. warningCategories.usersWarnings[user.userName] = warning = {
  1282. name: user.userName,
  1283. hosts: [_host.Hosts.host_name],
  1284. category: 'users',
  1285. onSingleHost: true
  1286. };
  1287. }
  1288. host.warnings.push(warning);
  1289. }, this);
  1290. }
  1291. //parse misc warnings for host
  1292. var umask = _host.Hosts.last_agent_env.umask;
  1293. if (umask && umask !== 18) {
  1294. warning = warnings.filterProperty('category', 'misc').findProperty('name', umask);
  1295. if (warning) {
  1296. warning.hosts.push(_host.Hosts.host_name);
  1297. warning.onSingleHost = false;
  1298. } else {
  1299. warning = {
  1300. name: umask,
  1301. hosts: [_host.Hosts.host_name],
  1302. category: 'misc',
  1303. onSingleHost: true
  1304. };
  1305. warnings.push(warning);
  1306. }
  1307. host.warnings.push(warning);
  1308. }
  1309. var firewallRunning = _host.Hosts.last_agent_env.iptablesIsRunning;
  1310. if (firewallRunning !== null && firewallRunning) {
  1311. var name = Em.I18n.t('installer.step3.hostWarningsPopup.firewall.name');
  1312. warning = warnings.filterProperty('category', 'firewall').findProperty('name', name);
  1313. if (warning) {
  1314. warning.hosts.push(_host.Hosts.host_name);
  1315. warning.onSingleHost = false;
  1316. } else {
  1317. warning = {
  1318. name: name,
  1319. hosts: [_host.Hosts.host_name],
  1320. category: 'firewall',
  1321. onSingleHost: true
  1322. };
  1323. warnings.push(warning);
  1324. }
  1325. host.warnings.push(warning);
  1326. }
  1327. if (_host.Hosts.last_agent_env.alternatives) {
  1328. _host.Hosts.last_agent_env.alternatives.forEach(function (alternative) {
  1329. warning = warningCategories.alternativeWarnings[alternative.name];
  1330. if (warning) {
  1331. warning.hosts.push(_host.Hosts.host_name);
  1332. warning.onSingleHost = false;
  1333. } else {
  1334. warningCategories.alternativeWarnings[alternative.name] = warning = {
  1335. name: alternative.name,
  1336. target: alternative.target,
  1337. hosts: [_host.Hosts.host_name],
  1338. category: 'alternatives',
  1339. onSingleHost: true
  1340. };
  1341. }
  1342. host.warnings.push(warning);
  1343. }, this);
  1344. }
  1345. if (_host.Hosts.last_agent_env.reverseLookup === false) {
  1346. var name = Em.I18n.t('installer.step3.hostWarningsPopup.reverseLookup.name');
  1347. warning = warnings.filterProperty('category', 'reverseLookup').findProperty('name', name);
  1348. if (warning) {
  1349. warning.hosts.push(_host.Hosts.host_name);
  1350. warning.onSingleHost = false;
  1351. } else {
  1352. warning = {
  1353. name: name,
  1354. hosts: [_host.Hosts.host_name],
  1355. category: 'reverseLookup',
  1356. onSingleHost: true
  1357. };
  1358. warnings.push(warning);
  1359. }
  1360. host.warnings.push(warning);
  1361. }
  1362. hosts.push(host);
  1363. }, this);
  1364. for (var categoryId in warningCategories) {
  1365. var category = warningCategories[categoryId]
  1366. for (var warningId in category) {
  1367. warnings.push(category[warningId]);
  1368. }
  1369. }
  1370. warnings.forEach(function (warn) {
  1371. if (warn.hosts.length < 11) {
  1372. warn.hostsList = warn.hosts.join('<br>')
  1373. } else {
  1374. warn.hostsList = warn.hosts.slice(0, 10).join('<br>') + '<br> ' + Em.I18n.t('installer.step3.hostWarningsPopup.moreHosts').format(warn.hosts.length - 10);
  1375. }
  1376. });
  1377. hosts.unshift({
  1378. name: 'All Hosts',
  1379. warnings: warnings
  1380. });
  1381. this.set('warnings', warnings);
  1382. this.set('warningsByHost', hosts);
  1383. this.set('isHostsWarningsLoaded', true);
  1384. },
  1385. /**
  1386. * Open popup that contain hosts' warnings
  1387. * @return {App.ModalPopup}
  1388. * @method hostWarningsPopup
  1389. */
  1390. hostWarningsPopup: function () {
  1391. var self = this;
  1392. return App.ModalPopup.show({
  1393. header: Em.I18n.t('installer.step3.warnings.popup.header'),
  1394. secondary: Em.I18n.t('installer.step3.hostWarningsPopup.rerunChecks'),
  1395. primary: Em.I18n.t('common.close'),
  1396. onPrimary: function () {
  1397. self.set('checksUpdateStatus', null);
  1398. this.hide();
  1399. },
  1400. onClose: function () {
  1401. self.set('checksUpdateStatus', null);
  1402. this.hide();
  1403. },
  1404. onSecondary: function () {
  1405. self.rerunChecks();
  1406. },
  1407. didInsertElement: function () {
  1408. this.fitHeight();
  1409. },
  1410. footerClass: App.WizardStep3HostWarningPopupFooter,
  1411. bodyClass: App.WizardStep3HostWarningPopupBody
  1412. });
  1413. },
  1414. /**
  1415. * Show popup with registered hosts
  1416. * @return {App.ModalPopup}
  1417. * @method registeredHostsPopup
  1418. */
  1419. registeredHostsPopup: function () {
  1420. var self = this;
  1421. return App.ModalPopup.show({
  1422. header: Em.I18n.t('installer.step3.warning.registeredHosts').format(this.get('registeredHosts').length),
  1423. secondary: null,
  1424. bodyClass: Em.View.extend({
  1425. templateName: require('templates/wizard/step3/step3_registered_hosts_popup'),
  1426. message: Em.I18n.t('installer.step3.registeredHostsPopup'),
  1427. registeredHosts: self.get('registeredHosts')
  1428. })
  1429. })
  1430. }
  1431. });