step3_controller.js 48 KB

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