installer.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  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 stringUtils = require('utils/string_utils');
  20. var validator = require('utils/validator');
  21. App.InstallerController = App.WizardController.extend({
  22. name: 'installerController',
  23. isCheckInProgress: false,
  24. totalSteps: 11,
  25. content: Em.Object.create({
  26. cluster: null,
  27. installOptions: null,
  28. hosts: null,
  29. services: null,
  30. slaveComponentHosts: null,
  31. masterComponentHosts: null,
  32. serviceConfigProperties: null,
  33. advancedServiceConfig: null,
  34. configGroups: [],
  35. slaveGroupProperties: null,
  36. stacks: null,
  37. clients: [],
  38. /**
  39. * recommendations for host groups loaded from server
  40. */
  41. recommendations: null,
  42. /**
  43. * recommendationsHostGroups - current component assignment after 5 and 6 steps,
  44. * or adding hiveserver2 interactive on "configure services" page
  45. * (uses for host groups validation and to load recommended configs)
  46. */
  47. recommendationsHostGroups: null,
  48. controllerName: 'installerController'
  49. }),
  50. /**
  51. * Wizard properties in local storage, which should be cleaned right after wizard has been finished
  52. */
  53. dbPropertiesToClean: [
  54. 'service',
  55. 'hosts',
  56. 'masterComponentHosts',
  57. 'slaveComponentHosts',
  58. 'cluster',
  59. 'allHostNames',
  60. 'installOptions',
  61. 'allHostNamesPattern',
  62. 'serviceComponents',
  63. 'clientInfo',
  64. 'selectedServiceNames',
  65. 'serviceConfigGroups',
  66. 'serviceConfigProperties',
  67. 'fileNamesToUpdate',
  68. 'bootStatus',
  69. 'stacksVersions',
  70. 'currentStep',
  71. 'serviceInfo',
  72. 'hostInfo',
  73. 'recommendations',
  74. 'recommendationsHostGroups',
  75. 'recommendationsConfigs'
  76. ],
  77. init: function () {
  78. this._super();
  79. this.get('isStepDisabled').setEach('value', true);
  80. this.get('isStepDisabled').pushObject(Ember.Object.create({
  81. step: 0,
  82. value: true
  83. }));
  84. },
  85. /**
  86. * redefined connectOutlet method to avoid view loading by unauthorized user
  87. * @param view
  88. * @param content
  89. */
  90. connectOutlet: function (view, content) {
  91. if (App.db.getAuthenticated()) {
  92. this._super(view, content);
  93. }
  94. },
  95. getCluster: function () {
  96. return jQuery.extend({}, this.get('clusterStatusTemplate'));
  97. },
  98. getHosts: function () {
  99. return [];
  100. },
  101. /**
  102. * Remove host from model. Used at <code>Confirm hosts(step2)</code> step
  103. * @param hosts Array of hosts, which we want to delete
  104. */
  105. removeHosts: function (hosts) {
  106. var dbHosts = this.getDBProperty('hosts');
  107. hosts.forEach(function (_hostInfo) {
  108. var host = _hostInfo.name;
  109. delete dbHosts[host];
  110. });
  111. this.setDBProperty('hosts', dbHosts);
  112. },
  113. /**
  114. * Load confirmed hosts.
  115. * Will be used at <code>Assign Masters(step5)</code> step
  116. */
  117. loadConfirmedHosts: function () {
  118. this.set('content.hosts', this.getDBProperty('hosts') || {});
  119. },
  120. /**
  121. * Load services data. Will be used at <code>Select services(step4)</code> step
  122. */
  123. loadServices: function () {
  124. var dfd = $.Deferred();
  125. var self = this;
  126. var stackServices = App.StackService.find().mapProperty('serviceName');
  127. if (!(stackServices && !!stackServices.length && App.StackService.find().objectAt(0).get('stackVersion') == App.get('currentStackVersionNumber'))) {
  128. this.loadServiceComponents().complete(function () {
  129. self.set('content.services', App.StackService.find().forEach(function (item) {
  130. // user the service version from VersionDefinition
  131. item.set('serviceVersionDisplay', App.Stack.find().findProperty('isSelected', true).get('stackServices').findProperty('name', item.get('serviceName')).get('latestVersion'));
  132. }));
  133. dfd.resolve();
  134. });
  135. } else {
  136. dfd.resolve();
  137. }
  138. return dfd.promise();
  139. },
  140. /**
  141. * total set of hosts registered to cluster, analog of App.Host model,
  142. * used in Installer wizard until hosts are installed
  143. */
  144. allHosts: function () {
  145. var rawHosts = this.get('content.hosts');
  146. var masterComponents = this.get('content.masterComponentHosts');
  147. var slaveComponents = this.get('content.slaveComponentHosts');
  148. var hosts = [];
  149. masterComponents.forEach(function (component) {
  150. var host = rawHosts[component.hostName];
  151. if (host.hostComponents) {
  152. host.hostComponents.push(Em.Object.create({
  153. componentName: component.component,
  154. displayName: component.display_name
  155. }));
  156. } else {
  157. rawHosts[component.hostName].hostComponents = [
  158. Em.Object.create({
  159. componentName: component.component,
  160. displayName: component.display_name
  161. })
  162. ]
  163. }
  164. });
  165. slaveComponents.forEach(function (component) {
  166. component.hosts.forEach(function (rawHost) {
  167. var host = rawHosts[rawHost.hostName];
  168. if (host.hostComponents) {
  169. host.hostComponents.push(Em.Object.create({
  170. componentName: component.componentName,
  171. displayName: component.displayName
  172. }));
  173. } else {
  174. rawHosts[rawHost.hostName].hostComponents = [
  175. Em.Object.create({
  176. componentName: component.componentName,
  177. displayName: component.displayName
  178. })
  179. ]
  180. }
  181. });
  182. });
  183. for (var hostName in rawHosts) {
  184. var host = rawHosts[hostName];
  185. var disksOverallCapacity = 0;
  186. var diskFree = 0;
  187. host.disk_info.forEach(function (disk) {
  188. disksOverallCapacity += parseFloat(disk.size);
  189. diskFree += parseFloat(disk.available);
  190. });
  191. hosts.pushObject(Em.Object.create({
  192. id: host.name,
  193. ip: host.ip,
  194. osType: host.os_type,
  195. osArch: host.os_arch,
  196. hostName: host.name,
  197. publicHostName: host.name,
  198. cpu: host.cpu,
  199. memory: host.memory,
  200. diskInfo: host.disk_info,
  201. diskTotal: disksOverallCapacity / (1024 * 1024),
  202. diskFree: diskFree / (1024 * 1024),
  203. hostComponents: host.hostComponents || []
  204. }
  205. ))
  206. }
  207. return hosts;
  208. }.property('content.hosts'),
  209. stacks: [],
  210. /**
  211. * stack names used as auxiliary data to query stacks by name
  212. */
  213. stackNames: [],
  214. /**
  215. * Load stacks data from server or take exist data from in memory variable {{content.stacks}}
  216. * The series of API calls will be called When landing first time on Select Stacks page
  217. * or on hitting refresh post select stacks page in installer wizard
  218. */
  219. loadStacks: function () {
  220. var stacks = this.get('content.stacks');
  221. var dfd = $.Deferred();
  222. if (stacks && stacks.get('length')) {
  223. App.set('currentStackVersion', App.Stack.find().findProperty('isSelected').get('stackNameVersion'));
  224. dfd.resolve(true);
  225. } else {
  226. App.ajax.send({
  227. name: 'wizard.stacks',
  228. sender: this,
  229. success: 'loadStacksSuccessCallback',
  230. error: 'loadStacksErrorCallback'
  231. }).complete(function () {
  232. dfd.resolve(false);
  233. });
  234. }
  235. return dfd.promise();
  236. },
  237. /**
  238. * Send queries to load versions for each stack
  239. */
  240. loadStacksSuccessCallback: function (data) {
  241. this.get('stacks').clear();
  242. this.set('stackNames', data.items.mapProperty('Stacks.stack_name'));
  243. },
  244. /**
  245. * onError callback for loading stacks data
  246. */
  247. loadStacksErrorCallback: function () {
  248. },
  249. /**
  250. * query every stack names from server
  251. * @return {Array}
  252. */
  253. loadStacksVersions: function () {
  254. var requests = [];
  255. this.get('stackNames').forEach(function (stackName) {
  256. requests.push(App.ajax.send({
  257. name: 'wizard.stacks_versions_definitions',
  258. sender: this,
  259. data: {
  260. stackName: stackName
  261. },
  262. success: 'loadStacksVersionsDefinitionsSuccessCallback',
  263. error: 'loadStacksVersionsErrorCallback'
  264. }));
  265. }, this);
  266. this.set('loadStacksRequestsCounter', requests.length);
  267. return requests;
  268. },
  269. /**
  270. * Counter for counting number of successful requests to load stack versions
  271. */
  272. loadStacksRequestsCounter: 0,
  273. /**
  274. * Parse loaded data and create array of stacks objects
  275. */
  276. loadStacksVersionsDefinitionsSuccessCallback: function (data) {
  277. var stacks = App.db.getStacks();
  278. var repos = App.db.getRepos();
  279. this.decrementProperty('loadStacksRequestsCounter');
  280. var isStacksExistInDb = stacks && stacks.length;
  281. if (isStacksExistInDb) {
  282. stacks.forEach(function (_stack) {
  283. var stack = data.items.findProperty('VersionDefinition.repository_version', _stack.repository_version);
  284. if (stack) {
  285. stack.VersionDefinition.is_selected = _stack.is_selected;
  286. }
  287. }, this);
  288. }
  289. data.items.sortProperty('VersionDefinition.stack_version').reverse().forEach(function (versionDefinition) {
  290. // to display repos panel, should map all available operating systems including empty ones
  291. var stackInfo = {};
  292. stackInfo.isStacksExistInDb = isStacksExistInDb;
  293. stackInfo.stacks = stacks;
  294. stackInfo.repos = repos;
  295. this.getSupportedOSList(versionDefinition, stackInfo);
  296. }, this);
  297. },
  298. mergeChanges: function (repos, stacks) {
  299. repos.forEach(function (repo) {
  300. App.Repository.find().findProperty('id', repo.id).set('baseUrl', repo.base_url);
  301. });
  302. stacks.forEach(function (_stack) {
  303. var stack = App.Stack.find().findProperty('id', _stack.id);
  304. if (stack) {
  305. stack.set('useRedhatSatellite', _stack.use_redhat_satellite);
  306. }
  307. });
  308. },
  309. setSelected: function (isStacksExistInDb) {
  310. if (!isStacksExistInDb) {
  311. var defaultStackVersion = App.Stack.find().findProperty('stackNameVersion', App.defaultStackVersion);
  312. if (defaultStackVersion) {
  313. defaultStackVersion.set('isSelected', true)
  314. } else {
  315. App.Stack.find().objectAt(0).set('isSelected', true);
  316. }
  317. }
  318. this.set('content.stacks', App.Stack.find());
  319. App.set('currentStackVersion', App.Stack.find().findProperty('isSelected').get('stackNameVersion'));
  320. },
  321. /**
  322. * Get the the repo version (to install) info, this data will be POST
  323. * @method startDeploy
  324. */
  325. getSelectedRepoVersionData: function () {
  326. var vdfData = App.db.getLocalRepoVDFData();
  327. var selectedStack = App.Stack.find().findProperty('isSelected', true);
  328. var isXMLdata = false;
  329. var data = {};
  330. if (selectedStack && selectedStack.get('showAvailable')) {
  331. //meaning user selected a public repo
  332. data = {
  333. "VersionDefinition": {
  334. "available": selectedStack.get('id')
  335. }
  336. };
  337. isXMLdata = false;
  338. } else if (vdfData && validator.isValidURL(vdfData)) {
  339. // meaning user uploaded a VDF via entering URL
  340. data = {
  341. "VersionDefinition": {
  342. "version_url": vdfData
  343. }
  344. };
  345. isXMLdata = false;
  346. } else if (vdfData) {
  347. // meaning user uploaded a local VDF.xml file
  348. isXMLdata = true;
  349. data = vdfData;
  350. } else {
  351. return null;
  352. }
  353. return {
  354. isXMLdata: isXMLdata,
  355. data: data
  356. };
  357. },
  358. /**
  359. * onError callback for loading stacks data
  360. */
  361. loadStacksVersionsErrorCallback: function () {
  362. },
  363. /**
  364. * check server version and web client version
  365. */
  366. checkServerClientVersion: function () {
  367. var dfd = $.Deferred();
  368. var self = this;
  369. self.getServerVersion().done(function () {
  370. dfd.resolve();
  371. });
  372. return dfd.promise();
  373. },
  374. getServerVersion: function () {
  375. return App.ajax.send({
  376. name: 'ambari.service',
  377. sender: this,
  378. data: {
  379. fields: '?fields=RootServiceComponents/component_version,RootServiceComponents/properties/server.os_family&minimal_response=true'
  380. },
  381. success: 'getServerVersionSuccessCallback',
  382. error: 'getServerVersionErrorCallback'
  383. });
  384. },
  385. getServerVersionSuccessCallback: function (data) {
  386. var clientVersion = App.get('version');
  387. var serverVersion = (data.RootServiceComponents.component_version).toString();
  388. this.set('ambariServerVersion', serverVersion);
  389. if (clientVersion) {
  390. this.set('versionConflictAlertBody', Em.I18n.t('app.versionMismatchAlert.body').format(serverVersion, clientVersion));
  391. this.set('isServerClientVersionMismatch', clientVersion != serverVersion);
  392. } else {
  393. this.set('isServerClientVersionMismatch', false);
  394. }
  395. App.set('isManagedMySQLForHiveEnabled', App.config.isManagedMySQLForHiveAllowed(data.RootServiceComponents.properties['server.os_family']));
  396. },
  397. getServerVersionErrorCallback: function () {
  398. },
  399. /**
  400. * set stacks from server to content and local DB
  401. */
  402. setStacks: function () {
  403. var stacks = App.Stack.find() || [];
  404. Em.assert('Stack model is not populated', stacks.get('length'));
  405. App.db.setStacks(stacks.slice());
  406. this.set('content.stacks', stacks);
  407. App.OperatingSystem.find().filterProperty('isSelected', false).forEach(function (os) {
  408. App.serviceMapper.deleteRecord(os);
  409. });
  410. var repos = App.Repository.find() || [];
  411. App.db.setRepos(repos.slice());
  412. },
  413. /**
  414. * Save data to model
  415. * @param stepController App.WizardStep4Controller
  416. */
  417. saveServices: function (stepController) {
  418. var selectedServiceNames = [];
  419. var installedServiceNames = [];
  420. stepController.filterProperty('isSelected').forEach(function (item) {
  421. selectedServiceNames.push(item.get('serviceName'));
  422. });
  423. stepController.filterProperty('isInstalled').forEach(function (item) {
  424. installedServiceNames.push(item.get('serviceName'));
  425. });
  426. this.set('content.services', App.StackService.find());
  427. this.set('content.selectedServiceNames', selectedServiceNames);
  428. this.set('content.installedServiceNames', installedServiceNames);
  429. this.setDBProperties({
  430. selectedServiceNames: selectedServiceNames,
  431. installedServiceNames: installedServiceNames
  432. });
  433. },
  434. /**
  435. * Save Master Component Hosts data to Main Controller
  436. * @param stepController App.WizardStep5Controller
  437. */
  438. saveMasterComponentHosts: function (stepController) {
  439. var obj = stepController.get('selectedServicesMasters'),
  440. hosts = this.getDBProperty('hosts');
  441. var masterComponentHosts = [];
  442. obj.forEach(function (_component) {
  443. masterComponentHosts.push({
  444. display_name: _component.get('display_name'),
  445. component: _component.get('component_name'),
  446. serviceId: _component.get('serviceId'),
  447. isInstalled: false,
  448. host_id: hosts[_component.get('selectedHost')].id
  449. });
  450. });
  451. this.setDBProperty('masterComponentHosts', masterComponentHosts);
  452. this.set('content.masterComponentHosts', masterComponentHosts);
  453. },
  454. /**
  455. * Load master component hosts data for using in required step controllers
  456. */
  457. loadMasterComponentHosts: function () {
  458. var props = this.getDBProperties(['masterComponentHosts', 'hosts']);
  459. var masterComponentHosts = props.masterComponentHosts,
  460. hosts = props.hosts || {},
  461. host_names = Em.keys(hosts);
  462. if (Em.isNone(masterComponentHosts)) {
  463. masterComponentHosts = [];
  464. }
  465. else {
  466. masterComponentHosts.forEach(function (component) {
  467. for (var i = 0; i < host_names.length; i++) {
  468. if (hosts[host_names[i]].id === component.host_id) {
  469. component.hostName = host_names[i];
  470. break;
  471. }
  472. }
  473. });
  474. }
  475. this.set("content.masterComponentHosts", masterComponentHosts);
  476. },
  477. loadCurrentHostGroups: function () {
  478. this.set("content.recommendationsHostGroups", this.getDBProperty('recommendationsHostGroups'));
  479. },
  480. loadRecommendationsConfigs: function () {
  481. App.router.set("wizardStep7Controller.recommendationsConfigs", this.getDBProperty('recommendationsConfigs'));
  482. },
  483. /**
  484. * Load master component hosts data for using in required step controllers
  485. */
  486. loadSlaveComponentHosts: function () {
  487. var props = this.getDBProperties(['slaveComponentHosts', 'hosts']);
  488. var slaveComponentHosts = props.slaveComponentHosts,
  489. hosts = props.hosts || {},
  490. host_names = Em.keys(hosts);
  491. if (!Em.isNone(slaveComponentHosts)) {
  492. slaveComponentHosts.forEach(function (component) {
  493. component.hosts.forEach(function (host) {
  494. for (var i = 0; i < host_names.length; i++) {
  495. if (hosts[host_names[i]].id === host.host_id) {
  496. host.hostName = host_names[i];
  497. break;
  498. }
  499. }
  500. });
  501. });
  502. }
  503. this.set("content.slaveComponentHosts", slaveComponentHosts);
  504. },
  505. /**
  506. * Load serviceConfigProperties to model
  507. */
  508. loadServiceConfigProperties: function () {
  509. var serviceConfigProperties = this.getDBProperty('serviceConfigProperties');
  510. this.set('content.serviceConfigProperties', serviceConfigProperties);
  511. },
  512. /**
  513. * Generate clients list for selected services and save it to model
  514. * @param stepController step4WizardController
  515. */
  516. saveClients: function (stepController) {
  517. var clients = [];
  518. stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
  519. var client = _service.get('serviceComponents').filterProperty('isClient', true);
  520. client.forEach(function (clientComponent) {
  521. clients.pushObject({
  522. component_name: clientComponent.get('componentName'),
  523. display_name: clientComponent.get('displayName'),
  524. isInstalled: false
  525. });
  526. }, this);
  527. }, this);
  528. this.setDBProperty('clientInfo', clients);
  529. this.set('content.clients', clients);
  530. },
  531. /*
  532. * Post version definition file (.xml) to server, DRY_RUN = TRUE
  533. */
  534. postVersionDefinitionFile: function (isXMLdata, data) {
  535. var dfd = $.Deferred();
  536. var name = isXMLdata? 'wizard.step1.post_version_definition_file.xml' : 'wizard.step1.post_version_definition_file.url';
  537. App.ajax.send({
  538. name: name,
  539. sender: this,
  540. data: {
  541. dfd: dfd,
  542. data: data
  543. },
  544. success: 'postVersionDefinitionFileSuccessCallback',
  545. error: 'postVersionDefinitionFileErrorCallback'
  546. });
  547. return dfd.promise();
  548. },
  549. /**
  550. * onSuccess callback for postVersionDefinitionFile.
  551. */
  552. postVersionDefinitionFileSuccessCallback: function (_data, request, dataInfo) {
  553. if (_data.resources.length && _data.resources[0].VersionDefinition) {
  554. var data = _data.resources[0];
  555. var self = this;
  556. // load the data info to display for details and contents panel
  557. data.VersionDefinition.id = dataInfo.data.VersionDefinition.available;
  558. var response = {
  559. id : data.VersionDefinition.id,
  560. stackVersion : data.VersionDefinition.stack_version,
  561. stackName: data.VersionDefinition.stack_name,
  562. type: data.VersionDefinition.type,
  563. stackNameVersion: data.VersionDefinition.stack_name + '-' + data.VersionDefinition.stack_version, /// HDP-2.3
  564. actualVersion: data.VersionDefinition.repository_version, /// 2.3.4.0-3846
  565. version: data.VersionDefinition.release ? data.VersionDefinition.release.version: null, /// 2.3.4.0
  566. releaseNotes: data.VersionDefinition.release ? data.VersionDefinition.release.notes: null,
  567. displayName: data.VersionDefinition.release ? data.VersionDefinition.stack_name + '-' + data.VersionDefinition.release.version :
  568. data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version, //HDP-2.3.4.0
  569. repoVersionFullName : data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version,
  570. osList: data.operating_systems,
  571. updateObj: data
  572. };
  573. var services = [];
  574. data.VersionDefinition.services.forEach(function (service) {
  575. services.push({
  576. name: service.name,
  577. version: service.versions[0].version,
  578. components: service.versions[0].components
  579. });
  580. });
  581. response.services = services;
  582. // to display repos panel, should map all available operating systems including empty ones
  583. var stackInfo = {};
  584. stackInfo.dfd = dataInfo.dfd;
  585. stackInfo.response = response;
  586. this.getSupportedOSList(data, stackInfo);
  587. }
  588. },
  589. /*
  590. * Post version definition file (.xml) to server in step 8
  591. */
  592. postVersionDefinitionFileStep8: function (isXMLdata, data) {
  593. var dfd = $.Deferred();
  594. var name = isXMLdata == true? 'wizard.step8.post_version_definition_file.xml' : 'wizard.step8.post_version_definition_file';
  595. App.ajax.send({
  596. name: name,
  597. sender: this,
  598. data: {
  599. dfd: dfd,
  600. data: data
  601. },
  602. success: 'postVersionDefinitionFileStep8SuccessCallback',
  603. error: 'postVersionDefinitionFileErrorCallback'
  604. });
  605. return dfd.promise();
  606. },
  607. /**
  608. * onSuccess callback for postVersionDefinitionFile.
  609. */
  610. postVersionDefinitionFileStep8SuccessCallback: function (response, request, data) {
  611. if (response.resources.length && response.resources[0].VersionDefinition) {
  612. data.dfd.resolve(
  613. {
  614. stackName: response.resources[0].VersionDefinition.stack_name,
  615. id: response.resources[0].VersionDefinition.id,
  616. stackVersion: response.resources[0].VersionDefinition.stack_version
  617. });
  618. }
  619. },
  620. /**
  621. * onError callback for postVersionDefinitionFile.
  622. */
  623. postVersionDefinitionFileErrorCallback: function (request, ajaxOptions, error, data, params) {
  624. params.dfd.reject(data);
  625. var header = Em.I18n.t('installer.step1.useLocalRepo.uploadFile.error.title');
  626. var body = "";
  627. if(request && request.responseText){
  628. try {
  629. var json = $.parseJSON(request.responseText);
  630. body = json.message;
  631. } catch (err) {}
  632. }
  633. App.showAlertPopup(header, body);
  634. },
  635. getSupportedOSList: function (versionDefinition, stackInfo) {
  636. this.incrementProperty('loadStacksRequestsCounter');
  637. return App.ajax.send({
  638. name: 'wizard.step1.get_supported_os_types',
  639. sender: this,
  640. data: {
  641. stackName: versionDefinition.VersionDefinition.stack_name,
  642. stackVersion: versionDefinition.VersionDefinition.stack_version,
  643. versionDefinition: versionDefinition,
  644. stackInfo: stackInfo
  645. },
  646. success: 'getSupportedOSListSuccessCallback',
  647. error: 'getSupportedOSListErrorCallback'
  648. });
  649. },
  650. /**
  651. * onSuccess callback for getSupportedOSList.
  652. */
  653. getSupportedOSListSuccessCallback: function (response, request, data) {
  654. var self = this;
  655. var existedOS = data.versionDefinition.operating_systems;
  656. var existedMap = {};
  657. existedOS.map(function (existedOS) {
  658. existedOS.isSelected = true;
  659. existedMap[existedOS.OperatingSystems.os_type] = existedOS;
  660. });
  661. response.operating_systems.forEach(function(supportedOS) {
  662. if(!existedMap[supportedOS.OperatingSystems.os_type]) {
  663. supportedOS.isSelected = false;
  664. supportedOS.repositories.forEach(function(repo) {
  665. repo.Repositories.base_url = '';
  666. });
  667. existedOS.push(supportedOS);
  668. }
  669. });
  670. App.stackMapper.map(data.versionDefinition);
  671. if (!this.decrementProperty('loadStacksRequestsCounter')) {
  672. if (data.stackInfo.dfd) {
  673. data.stackInfo.dfd.resolve(data.stackInfo.response);
  674. } else {
  675. var versionData = this.getSelectedRepoVersionData();
  676. if (versionData) {
  677. this.postVersionDefinitionFile(versionData.isXMLdata, versionData.data).done(function (versionInfo) {
  678. self.mergeChanges(data.stackInfo.repos, data.stackInfo.stacks);
  679. App.Stack.find().setEach('isSelected', false);
  680. var stackId = versionData.data.VersionDefinition.available || versionInfo.stackNameVersion + "-" + versionInfo.actualVersion;
  681. App.Stack.find().findProperty('id', stackId).set('isSelected', true);
  682. self.setSelected(data.stackInfo.isStacksExistInDb);
  683. });
  684. } else {
  685. this.setSelected(data.stackInfo.isStacksExistInDb);
  686. }
  687. }
  688. }
  689. },
  690. /**
  691. * onError callback for getSupportedOSList
  692. */
  693. getSupportedOSListErrorCallback: function (request, ajaxOptions, error, data, params) {
  694. var header = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.error.title');
  695. var body = "";
  696. if(request && request.responseText){
  697. try {
  698. var json = $.parseJSON(request.responseText);
  699. body = json.message;
  700. } catch (err) {}
  701. }
  702. App.showAlertPopup(header, body);
  703. },
  704. updateRepoOSInfo: function (repoToUpdate, repo) {
  705. var deferred = $.Deferred();
  706. var repoVersion = this.prepareRepoForSaving(repo);
  707. App.ajax.send({
  708. name: 'admin.stack_versions.edit.repo',
  709. sender: this,
  710. data: {
  711. stackName: repoToUpdate.stackName,
  712. stackVersion: repoToUpdate.stackVersion,
  713. repoVersionId: repoToUpdate.id,
  714. repoVersion: repoVersion
  715. }
  716. }).success(function() {
  717. deferred.resolve([]);
  718. }).error(function() {
  719. deferred.resolve([]);
  720. });
  721. return deferred.promise();
  722. },
  723. /**
  724. * transform repo data into json for
  725. * saving changes to repository version
  726. * @param {Em.Object} repo
  727. * @returns {{operating_systems: Array}}
  728. */
  729. prepareRepoForSaving: function(repo) {
  730. var repoVersion = { "operating_systems": [] };
  731. var ambari_managed_repositories = !repo.get('useRedhatSatellite');
  732. repo.get('operatingSystems').forEach(function (os, k) {
  733. repoVersion.operating_systems.push({
  734. "OperatingSystems": {
  735. "os_type": os.get("osType"),
  736. "ambari_managed_repositories": ambari_managed_repositories
  737. },
  738. "repositories": []
  739. });
  740. os.get('repositories').forEach(function (repository) {
  741. repoVersion.operating_systems[k].repositories.push({
  742. "Repositories": {
  743. "base_url": repository.get('baseUrl'),
  744. "repo_id": repository.get('repoId'),
  745. "repo_name": repository.get('repoName')
  746. }
  747. });
  748. });
  749. });
  750. return repoVersion;
  751. },
  752. /**
  753. * Check validation of the customized local urls
  754. */
  755. checkRepoURL: function (wizardStep1Controller) {
  756. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  757. selectedStack.set('reload', true);
  758. var nameVersionCombo = selectedStack.get('stackNameVersion');
  759. var stackName = nameVersionCombo.split('-')[0];
  760. var stackVersion = nameVersionCombo.split('-')[1];
  761. var dfd = $.Deferred();
  762. if (selectedStack && selectedStack.get('operatingSystems')) {
  763. this.set('validationCnt', selectedStack.get('repositories').filterProperty('isSelected').length);
  764. var verifyBaseUrl = !wizardStep1Controller.get('skipValidationChecked') && !wizardStep1Controller.get('selectedStack.useRedhatSatellite');
  765. selectedStack.get('operatingSystems').forEach(function (os) {
  766. if (os.get('isSelected')) {
  767. os.get('repositories').forEach(function (repo) {
  768. repo.setProperties({
  769. errorTitle: '',
  770. errorContent: '',
  771. validation: App.Repository.validation['INPROGRESS']
  772. });
  773. this.set('content.isCheckInProgress', true);
  774. App.ajax.send({
  775. name: 'wizard.advanced_repositories.valid_url',
  776. sender: this,
  777. data: {
  778. stackName: stackName,
  779. stackVersion: stackVersion,
  780. repoId: repo.get('repoId'),
  781. osType: os.get('osType'),
  782. osId: os.get('id'),
  783. dfd: dfd,
  784. data: {
  785. 'Repositories': {
  786. 'base_url': repo.get('baseUrl'),
  787. "verify_base_url": verifyBaseUrl
  788. }
  789. }
  790. },
  791. success: 'checkRepoURLSuccessCallback',
  792. error: 'checkRepoURLErrorCallback'
  793. });
  794. }, this);
  795. }
  796. }, this);
  797. }
  798. return dfd.promise();
  799. },
  800. /**
  801. * onSuccess callback for check Repo URL.
  802. */
  803. checkRepoURLSuccessCallback: function (response, request, data) {
  804. var selectedStack = this.get('content.stacks').findProperty('isSelected');
  805. if (selectedStack && selectedStack.get('operatingSystems')) {
  806. var os = selectedStack.get('operatingSystems').findProperty('id', data.osId);
  807. var repo = os.get('repositories').findProperty('repoId', data.repoId);
  808. if (repo) {
  809. repo.set('validation', App.Repository.validation['OK']);
  810. }
  811. }
  812. this.set('validationCnt', this.get('validationCnt') - 1);
  813. if (!this.get('validationCnt')) {
  814. this.set('content.isCheckInProgress', false);
  815. data.dfd.resolve();
  816. }
  817. },
  818. /**
  819. * onError callback for check Repo URL.
  820. */
  821. checkRepoURLErrorCallback: function (request, ajaxOptions, error, data, params) {
  822. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  823. if (selectedStack && selectedStack.get('operatingSystems')) {
  824. var os = selectedStack.get('operatingSystems').findProperty('id', params.osId);
  825. var repo = os.get('repositories').findProperty('repoId', params.repoId);
  826. if (repo) {
  827. repo.setProperties({
  828. validation: App.Repository.validation['INVALID'],
  829. errorTitle: request.status + ":" + request.statusText,
  830. errorContent: $.parseJSON(request.responseText) ? $.parseJSON(request.responseText).message : ""
  831. });
  832. }
  833. }
  834. this.set('content.isCheckInProgress', false);
  835. params.dfd.reject();
  836. },
  837. loadMap: {
  838. '0': [
  839. {
  840. type: 'sync',
  841. callback: function () {
  842. this.load('cluster');
  843. }
  844. }
  845. ],
  846. '1': [
  847. {
  848. type: 'async',
  849. callback: function () {
  850. var dfd = $.Deferred();
  851. this.loadStacks().always(function() {
  852. App.router.get('clusterController').loadAmbariProperties().always(function() {
  853. dfd.resolve();
  854. });
  855. });
  856. return dfd.promise();
  857. }
  858. },
  859. {
  860. type: 'async',
  861. callback: function (stacksLoaded) {
  862. var dfd = $.Deferred();
  863. if (!stacksLoaded) {
  864. $.when.apply(this, this.loadStacksVersions()).done(function () {
  865. Em.run.later('sync', function() {
  866. dfd.resolve(stacksLoaded);
  867. }, 1000);
  868. });
  869. } else {
  870. dfd.resolve(stacksLoaded);
  871. }
  872. return dfd.promise();
  873. }
  874. }
  875. ],
  876. '2': [
  877. {
  878. type: 'sync',
  879. callback: function () {
  880. this.load('installOptions');
  881. }
  882. }
  883. ],
  884. '3': [
  885. {
  886. type: 'sync',
  887. callback: function () {
  888. this.loadConfirmedHosts();
  889. }
  890. }
  891. ],
  892. '4': [
  893. {
  894. type: 'async',
  895. callback: function () {
  896. return this.loadServices();
  897. }
  898. }
  899. ],
  900. '5': [
  901. {
  902. type: 'sync',
  903. callback: function () {
  904. this.setSkipSlavesStep(App.StackService.find().filterProperty('isSelected'), 6);
  905. this.loadMasterComponentHosts();
  906. this.loadConfirmedHosts();
  907. this.loadRecommendations();
  908. }
  909. }
  910. ],
  911. '6': [
  912. {
  913. type: 'sync',
  914. callback: function () {
  915. this.loadSlaveComponentHosts();
  916. this.loadClients();
  917. this.loadRecommendations();
  918. }
  919. }
  920. ],
  921. '7': [
  922. {
  923. type: 'async',
  924. callback: function () {
  925. this.loadServiceConfigGroups();
  926. this.loadServiceConfigProperties();
  927. this.loadCurrentHostGroups();
  928. this.loadRecommendationsConfigs();
  929. return this.loadConfigThemes();
  930. }
  931. }
  932. ]
  933. },
  934. /**
  935. * Clear all temporary data
  936. */
  937. finish: function () {
  938. this.setCurrentStep('0');
  939. this.clearStorageData();
  940. App.router.get('userSettingsController').postUserPref('show_bg', true);
  941. },
  942. /**
  943. * Save cluster provisioning state to the server
  944. * @param state cluster provisioning state
  945. */
  946. setClusterProvisioningState: function (state) {
  947. return App.ajax.send({
  948. name: 'cluster.save_provisioning_state',
  949. sender: this,
  950. data: {
  951. state: state
  952. }
  953. });
  954. },
  955. setStepsEnable: function () {
  956. for (var i = 0; i <= this.totalSteps; i++) {
  957. this.get('isStepDisabled').findProperty('step', i).set('value', i > this.get('currentStep'));
  958. }
  959. }.observes('currentStep'),
  960. setLowerStepsDisable: function (stepNo) {
  961. for (var i = 0; i < stepNo; i++) {
  962. var step = this.get('isStepDisabled').findProperty('step', i);
  963. step.set('value', true);
  964. }
  965. },
  966. /**
  967. * Compare jdk versions used for ambari and selected stack.
  968. * Validation check will fire only for non-custom jdk configuration.
  969. *
  970. * @param {Function} successCallback
  971. * @param {Function} failCallback
  972. */
  973. validateJDKVersion: function (successCallback, failCallback) {
  974. var selectedStack = App.Stack.find().findProperty('isSelected', true),
  975. currentJDKVersion = App.router.get('clusterController.ambariProperties')['java.version'],
  976. // use min as max, or max as min version, in case when some of them missed
  977. minJDKVersion = selectedStack.get('minJdkVersion') || selectedStack.get('maxJdkVersion'),
  978. maxJDKVersion = selectedStack.get('maxJdkVersion') || selectedStack.get('minJdkVersion'),
  979. t = Em.I18n.t,
  980. fCallback = failCallback || function() {},
  981. sCallback = successCallback || function() {};
  982. // Skip jdk check if min and max required version not set in stack definition.
  983. if (!minJDKVersion && !maxJDKVersion) {
  984. sCallback();
  985. return;
  986. }
  987. if (currentJDKVersion) {
  988. if (stringUtils.compareVersions(currentJDKVersion, minJDKVersion) < 0 ||
  989. stringUtils.compareVersions(maxJDKVersion, currentJDKVersion) < 0) {
  990. // checks and process only minor part for now
  991. var versionDistance = parseInt(maxJDKVersion.split('.')[1]) - parseInt(minJDKVersion.split('.')[1]);
  992. var versionsList = [minJDKVersion];
  993. for (var i = 1; i < (versionDistance + 1); i++) {
  994. versionsList.push("" + minJDKVersion.split('.')[0] + '.' + (+minJDKVersion.split('.')[1] + i));
  995. }
  996. var versionsString = stringUtils.getFormattedStringFromArray(versionsList, t('or'));
  997. var popupBody = t('popup.jdkValidation.body').format(selectedStack.get('stackName') + ' ' + selectedStack.get('stackVersion'), versionsString, currentJDKVersion);
  998. App.showConfirmationPopup(sCallback, popupBody, fCallback, t('popup.jdkValidation.header'), t('common.proceedAnyway'), true);
  999. return;
  1000. }
  1001. }
  1002. sCallback();
  1003. }
  1004. });