step3_controller.js 45 KB

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