installer.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  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. var _repos = repos || [];
  300. var _stacks = stacks || [];
  301. _repos.forEach(function (repo) {
  302. App.Repository.find().findProperty('id', repo.id).set('baseUrl', repo.base_url);
  303. });
  304. _stacks.forEach(function (_stack) {
  305. var stack = App.Stack.find().findProperty('id', _stack.id);
  306. if (stack) {
  307. stack.set('useRedhatSatellite', _stack.use_redhat_satellite);
  308. }
  309. });
  310. },
  311. setSelected: function (isStacksExistInDb) {
  312. if (!isStacksExistInDb) {
  313. var stacks = App.Stack.find();
  314. stacks.setEach('isSelected', false);
  315. stacks.sortProperty('id').set('lastObject.isSelected', true);
  316. }
  317. this.set('content.stacks', App.Stack.find());
  318. App.set('currentStackVersion', App.Stack.find().findProperty('isSelected').get('stackNameVersion'));
  319. },
  320. /**
  321. * Get the the repo version (to install) info, this data will be POST
  322. * @method startDeploy
  323. */
  324. getSelectedRepoVersionData: function () {
  325. var vdfData = App.db.getLocalRepoVDFData();
  326. var selectedStack = App.Stack.find().findProperty('isSelected', true);
  327. var isXMLdata = false;
  328. var data = {};
  329. if (selectedStack && selectedStack.get('showAvailable')) {
  330. //meaning user selected a public repo
  331. data = {
  332. "VersionDefinition": {
  333. "available": selectedStack.get('id')
  334. }
  335. };
  336. isXMLdata = false;
  337. } else if (vdfData && validator.isValidURL(vdfData)) {
  338. // meaning user uploaded a VDF via entering URL
  339. data = {
  340. "VersionDefinition": {
  341. "version_url": vdfData
  342. }
  343. };
  344. isXMLdata = false;
  345. } else if (vdfData) {
  346. // meaning user uploaded a local VDF.xml file
  347. isXMLdata = true;
  348. data = vdfData;
  349. } else {
  350. return null;
  351. }
  352. return {
  353. isXMLdata: isXMLdata,
  354. data: data
  355. };
  356. },
  357. /**
  358. * onError callback for loading stacks data
  359. */
  360. loadStacksVersionsErrorCallback: function () {
  361. },
  362. /**
  363. * check server version and web client version
  364. */
  365. checkServerClientVersion: function () {
  366. var dfd = $.Deferred();
  367. var self = this;
  368. self.getServerVersion().done(function () {
  369. dfd.resolve();
  370. });
  371. return dfd.promise();
  372. },
  373. getServerVersion: function () {
  374. return App.ajax.send({
  375. name: 'ambari.service',
  376. sender: this,
  377. data: {
  378. fields: '?fields=RootServiceComponents/component_version,RootServiceComponents/properties/server.os_family&minimal_response=true'
  379. },
  380. success: 'getServerVersionSuccessCallback',
  381. error: 'getServerVersionErrorCallback'
  382. });
  383. },
  384. getServerVersionSuccessCallback: function (data) {
  385. var clientVersion = App.get('version');
  386. var serverVersion = data.RootServiceComponents.component_version.toString();
  387. this.set('ambariServerVersion', serverVersion);
  388. if (clientVersion) {
  389. this.set('versionConflictAlertBody', Em.I18n.t('app.versionMismatchAlert.body').format(serverVersion, clientVersion));
  390. this.set('isServerClientVersionMismatch', clientVersion !== serverVersion);
  391. } else {
  392. this.set('isServerClientVersionMismatch', false);
  393. }
  394. App.set('isManagedMySQLForHiveEnabled', App.config.isManagedMySQLForHiveAllowed(data.RootServiceComponents.properties['server.os_family']));
  395. },
  396. getServerVersionErrorCallback: function () {
  397. },
  398. /**
  399. * set stacks from server to content and local DB
  400. */
  401. setStacks: function () {
  402. var stacks = App.Stack.find() || [];
  403. Em.assert('Stack model is not populated', stacks.get('length'));
  404. App.db.setStacks(stacks.slice());
  405. this.set('content.stacks', stacks);
  406. var repos = App.Repository.find() || [];
  407. App.db.setRepos(repos.slice());
  408. },
  409. /**
  410. * Save data to model
  411. * @param stepController App.WizardStep4Controller
  412. */
  413. saveServices: function (stepController) {
  414. var selectedServiceNames = [];
  415. var installedServiceNames = [];
  416. stepController.filterProperty('isSelected').forEach(function (item) {
  417. selectedServiceNames.push(item.get('serviceName'));
  418. });
  419. stepController.filterProperty('isInstalled').forEach(function (item) {
  420. installedServiceNames.push(item.get('serviceName'));
  421. });
  422. this.set('content.services', App.StackService.find());
  423. this.set('content.selectedServiceNames', selectedServiceNames);
  424. this.set('content.installedServiceNames', installedServiceNames);
  425. this.setDBProperties({
  426. selectedServiceNames: selectedServiceNames,
  427. installedServiceNames: installedServiceNames
  428. });
  429. },
  430. /**
  431. * Save Master Component Hosts data to Main Controller
  432. * @param stepController App.WizardStep5Controller
  433. */
  434. saveMasterComponentHosts: function (stepController) {
  435. var obj = stepController.get('selectedServicesMasters'),
  436. hosts = this.getDBProperty('hosts');
  437. var masterComponentHosts = [];
  438. obj.forEach(function (_component) {
  439. masterComponentHosts.push({
  440. display_name: _component.get('display_name'),
  441. component: _component.get('component_name'),
  442. serviceId: _component.get('serviceId'),
  443. isInstalled: false,
  444. host_id: hosts[_component.get('selectedHost')].id
  445. });
  446. });
  447. this.setDBProperty('masterComponentHosts', masterComponentHosts);
  448. this.set('content.masterComponentHosts', masterComponentHosts);
  449. },
  450. /**
  451. * Load master component hosts data for using in required step controllers
  452. */
  453. loadMasterComponentHosts: function () {
  454. var props = this.getDBProperties(['masterComponentHosts', 'hosts']);
  455. var masterComponentHosts = props.masterComponentHosts,
  456. hosts = props.hosts || {},
  457. hostNames = Em.keys(hosts);
  458. if (Em.isNone(masterComponentHosts)) {
  459. masterComponentHosts = [];
  460. }
  461. else {
  462. masterComponentHosts.forEach(function (component) {
  463. for (var i = 0; i < hostNames.length; i++) {
  464. if (hosts[hostNames[i]].id === component.host_id) {
  465. component.hostName = hostNames[i];
  466. break;
  467. }
  468. }
  469. });
  470. }
  471. this.set("content.masterComponentHosts", masterComponentHosts);
  472. },
  473. loadCurrentHostGroups: function () {
  474. this.set("content.recommendationsHostGroups", this.getDBProperty('recommendationsHostGroups'));
  475. },
  476. loadRecommendationsConfigs: function () {
  477. App.router.set("wizardStep7Controller.recommendationsConfigs", this.getDBProperty('recommendationsConfigs'));
  478. },
  479. /**
  480. * Load master component hosts data for using in required step controllers
  481. */
  482. loadSlaveComponentHosts: function () {
  483. var props = this.getDBProperties(['slaveComponentHosts', 'hosts']);
  484. var slaveComponentHosts = props.slaveComponentHosts,
  485. hosts = props.hosts || {},
  486. hostNames = Em.keys(hosts);
  487. if (!Em.isNone(slaveComponentHosts)) {
  488. slaveComponentHosts.forEach(function (component) {
  489. component.hosts.forEach(function (host) {
  490. for (var i = 0; i < hostNames.length; i++) {
  491. if (hosts[hostNames[i]].id === host.host_id) {
  492. host.hostName = hostNames[i];
  493. break;
  494. }
  495. }
  496. });
  497. });
  498. }
  499. this.set("content.slaveComponentHosts", slaveComponentHosts);
  500. },
  501. /**
  502. * Load serviceConfigProperties to model
  503. */
  504. loadServiceConfigProperties: function () {
  505. var serviceConfigProperties = this.getDBProperty('serviceConfigProperties');
  506. this.set('content.serviceConfigProperties', serviceConfigProperties);
  507. },
  508. /**
  509. * Generate clients list for selected services and save it to model
  510. * @param stepController step4WizardController
  511. */
  512. saveClients: function (stepController) {
  513. var clients = [];
  514. stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
  515. var client = _service.get('serviceComponents').filterProperty('isClient', true);
  516. client.forEach(function (clientComponent) {
  517. clients.pushObject({
  518. component_name: clientComponent.get('componentName'),
  519. display_name: clientComponent.get('displayName'),
  520. isInstalled: false
  521. });
  522. }, this);
  523. }, this);
  524. this.setDBProperty('clientInfo', clients);
  525. this.set('content.clients', clients);
  526. },
  527. /*
  528. * Post version definition file (.xml) to server, DRY_RUN = TRUE
  529. */
  530. postVersionDefinitionFile: function (isXMLdata, data) {
  531. var dfd = $.Deferred();
  532. var name = isXMLdata? 'wizard.step1.post_version_definition_file.xml' : 'wizard.step1.post_version_definition_file.url';
  533. App.ajax.send({
  534. name: name,
  535. sender: this,
  536. data: {
  537. dfd: dfd,
  538. data: data
  539. },
  540. success: 'postVersionDefinitionFileSuccessCallback',
  541. error: 'postVersionDefinitionFileErrorCallback'
  542. });
  543. return dfd.promise();
  544. },
  545. /**
  546. * onSuccess callback for postVersionDefinitionFile.
  547. */
  548. postVersionDefinitionFileSuccessCallback: function (_data, request, dataInfo) {
  549. if (_data.resources.length && _data.resources[0].VersionDefinition) {
  550. var data = _data.resources[0];
  551. // load the data info to display for details and contents panel
  552. data.VersionDefinition.id = Em.get(dataInfo, 'data.VersionDefinition.available') || data.VersionDefinition.id;
  553. var response = {
  554. id : data.VersionDefinition.id,
  555. stackVersion : data.VersionDefinition.stack_version,
  556. stackName: data.VersionDefinition.stack_name,
  557. type: data.VersionDefinition.type,
  558. stackNameVersion: data.VersionDefinition.stack_name + '-' + data.VersionDefinition.stack_version, /// HDP-2.3
  559. actualVersion: data.VersionDefinition.repository_version, /// 2.3.4.0-3846
  560. version: data.VersionDefinition.release ? data.VersionDefinition.release.version: null, /// 2.3.4.0
  561. releaseNotes: data.VersionDefinition.release ? data.VersionDefinition.release.notes: null,
  562. displayName: data.VersionDefinition.release ? data.VersionDefinition.stack_name + '-' + data.VersionDefinition.release.version :
  563. data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version, //HDP-2.3.4.0
  564. repoVersionFullName : data.VersionDefinition.stack_name + '-' + data.VersionDefinition.repository_version,
  565. osList: data.operating_systems,
  566. updateObj: data
  567. };
  568. var services = [];
  569. data.VersionDefinition.services.forEach(function (service) {
  570. services.push({
  571. name: service.name,
  572. version: service.versions[0].version,
  573. components: service.versions[0].components
  574. });
  575. });
  576. response.services = services;
  577. // to display repos panel, should map all available operating systems including empty ones
  578. var stackInfo = {};
  579. stackInfo.dfd = dataInfo.dfd;
  580. stackInfo.response = response;
  581. this.getSupportedOSList(data, stackInfo);
  582. }
  583. },
  584. /*
  585. * Post version definition file (.xml) to server in step 8
  586. */
  587. postVersionDefinitionFileStep8: function (isXMLdata, data) {
  588. var dfd = $.Deferred();
  589. var name = isXMLdata == true? 'wizard.step8.post_version_definition_file.xml' : 'wizard.step8.post_version_definition_file';
  590. App.ajax.send({
  591. name: name,
  592. sender: this,
  593. data: {
  594. dfd: dfd,
  595. data: data
  596. },
  597. success: 'postVersionDefinitionFileStep8SuccessCallback',
  598. error: 'postVersionDefinitionFileErrorCallback'
  599. });
  600. return dfd.promise();
  601. },
  602. /**
  603. * onSuccess callback for postVersionDefinitionFile.
  604. */
  605. postVersionDefinitionFileStep8SuccessCallback: function (response, request, data) {
  606. if (response.resources.length && response.resources[0].VersionDefinition) {
  607. data.dfd.resolve(
  608. {
  609. stackName: response.resources[0].VersionDefinition.stack_name,
  610. id: response.resources[0].VersionDefinition.id,
  611. stackVersion: response.resources[0].VersionDefinition.stack_version
  612. });
  613. }
  614. },
  615. /**
  616. * onError callback for postVersionDefinitionFile.
  617. */
  618. postVersionDefinitionFileErrorCallback: function (request, ajaxOptions, error, data, params) {
  619. params.dfd.reject(data);
  620. var header = Em.I18n.t('installer.step1.useLocalRepo.uploadFile.error.title');
  621. var body = '';
  622. if(request && request.responseText) {
  623. try {
  624. var json = $.parseJSON(request.responseText);
  625. body = json.message;
  626. } catch (err) {}
  627. }
  628. App.db.setLocalRepoVDFData(undefined);
  629. App.showAlertPopup(header, body);
  630. },
  631. getSupportedOSList: function (versionDefinition, stackInfo) {
  632. this.incrementProperty('loadStacksRequestsCounter');
  633. return App.ajax.send({
  634. name: 'wizard.step1.get_supported_os_types',
  635. sender: this,
  636. data: {
  637. stackName: versionDefinition.VersionDefinition.stack_name,
  638. stackVersion: versionDefinition.VersionDefinition.stack_version,
  639. versionDefinition: versionDefinition,
  640. stackInfo: stackInfo
  641. },
  642. success: 'getSupportedOSListSuccessCallback',
  643. error: 'getSupportedOSListErrorCallback'
  644. });
  645. },
  646. /**
  647. * onSuccess callback for getSupportedOSList.
  648. */
  649. getSupportedOSListSuccessCallback: function (response, request, data) {
  650. var self = this;
  651. var existedOS = data.versionDefinition.operating_systems;
  652. var existedMap = {};
  653. existedOS.map(function (existedOS) {
  654. existedOS.isSelected = true;
  655. existedMap[existedOS.OperatingSystems.os_type] = existedOS;
  656. });
  657. response.operating_systems.forEach(function(supportedOS) {
  658. if(!existedMap[supportedOS.OperatingSystems.os_type]) {
  659. supportedOS.isSelected = false;
  660. supportedOS.repositories.forEach(function(repo) {
  661. repo.Repositories.base_url = '';
  662. });
  663. existedOS.push(supportedOS);
  664. }
  665. });
  666. App.stackMapper.map(data.versionDefinition);
  667. if (!this.decrementProperty('loadStacksRequestsCounter')) {
  668. if (data.stackInfo.dfd) {
  669. data.stackInfo.dfd.resolve(data.stackInfo.response);
  670. } else {
  671. var versionData = this.getSelectedRepoVersionData();
  672. if (versionData) {
  673. this.postVersionDefinitionFile(versionData.isXMLdata, versionData.data).done(function (versionInfo) {
  674. self.mergeChanges(data.stackInfo.repos, data.stackInfo.stacks);
  675. App.Stack.find().setEach('isSelected', false);
  676. var stackId = Em.get(versionData, 'data.VersionDefinition.available') || versionInfo.stackNameVersion + "-" + versionInfo.actualVersion;
  677. App.Stack.find().findProperty('id', stackId).set('isSelected', true);
  678. self.setSelected(data.stackInfo.isStacksExistInDb);
  679. }).fail(function () {
  680. self.setSelected(data.stackInfo.isStacksExistInDb);
  681. });
  682. } else {
  683. this.setSelected(data.stackInfo.isStacksExistInDb);
  684. }
  685. }
  686. }
  687. },
  688. /**
  689. * onError callback for getSupportedOSList
  690. */
  691. getSupportedOSListErrorCallback: function (request, ajaxOptions, error, data, params) {
  692. var header = Em.I18n.t('installer.step1.useLocalRepo.getSurpottedOs.error.title');
  693. var body = "";
  694. if(request && request.responseText){
  695. try {
  696. var json = $.parseJSON(request.responseText);
  697. body = json.message;
  698. } catch (err) {}
  699. }
  700. App.showAlertPopup(header, body);
  701. },
  702. updateRepoOSInfo: function (repoToUpdate, repo) {
  703. var deferred = $.Deferred();
  704. var repoVersion = this.prepareRepoForSaving(repo);
  705. App.ajax.send({
  706. name: 'admin.stack_versions.edit.repo',
  707. sender: this,
  708. data: {
  709. stackName: repoToUpdate.stackName,
  710. stackVersion: repoToUpdate.stackVersion,
  711. repoVersionId: repoToUpdate.id,
  712. repoVersion: repoVersion
  713. }
  714. }).success(function() {
  715. deferred.resolve([]);
  716. }).error(function() {
  717. deferred.resolve([]);
  718. });
  719. return deferred.promise();
  720. },
  721. /**
  722. * transform repo data into json for
  723. * saving changes to repository version
  724. * @param {Em.Object} repo
  725. * @returns {{operating_systems: Array}}
  726. */
  727. prepareRepoForSaving: function(repo) {
  728. var repoVersion = { "operating_systems": [] };
  729. var ambariManagedRepositories = !repo.get('useRedhatSatellite');
  730. repo.get('operatingSystems').forEach(function (os, k) {
  731. repoVersion.operating_systems.push({
  732. "OperatingSystems": {
  733. "os_type": os.get("osType"),
  734. "ambari_managed_repositories": ambariManagedRepositories
  735. },
  736. "repositories": []
  737. });
  738. os.get('repositories').forEach(function (repository) {
  739. repoVersion.operating_systems[k].repositories.push({
  740. "Repositories": {
  741. "base_url": repository.get('baseUrl'),
  742. "repo_id": repository.get('repoId'),
  743. "repo_name": repository.get('repoName')
  744. }
  745. });
  746. });
  747. });
  748. return repoVersion;
  749. },
  750. /**
  751. * Check validation of the customized local urls
  752. */
  753. checkRepoURL: function (wizardStep1Controller) {
  754. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  755. selectedStack.set('reload', true);
  756. var nameVersionCombo = selectedStack.get('stackNameVersion');
  757. var stackName = nameVersionCombo.split('-')[0];
  758. var stackVersion = nameVersionCombo.split('-')[1];
  759. var dfd = $.Deferred();
  760. if (selectedStack && selectedStack.get('operatingSystems')) {
  761. this.set('validationCnt', selectedStack.get('repositories').filterProperty('isSelected').length);
  762. var verifyBaseUrl = !wizardStep1Controller.get('skipValidationChecked') && !wizardStep1Controller.get('selectedStack.useRedhatSatellite');
  763. selectedStack.get('operatingSystems').forEach(function (os) {
  764. if (os.get('isSelected')) {
  765. os.get('repositories').forEach(function (repo) {
  766. repo.setProperties({
  767. errorTitle: '',
  768. errorContent: '',
  769. validation: App.Repository.validation.INPROGRESS
  770. });
  771. this.set('content.isCheckInProgress', true);
  772. App.ajax.send({
  773. name: 'wizard.advanced_repositories.valid_url',
  774. sender: this,
  775. data: {
  776. stackName: stackName,
  777. stackVersion: stackVersion,
  778. repoId: repo.get('repoId'),
  779. osType: os.get('osType'),
  780. osId: os.get('id'),
  781. dfd: dfd,
  782. data: {
  783. 'Repositories': {
  784. 'base_url': repo.get('baseUrl'),
  785. "verify_base_url": verifyBaseUrl
  786. }
  787. }
  788. },
  789. success: 'checkRepoURLSuccessCallback',
  790. error: 'checkRepoURLErrorCallback'
  791. });
  792. }, this);
  793. }
  794. }, this);
  795. }
  796. return dfd.promise();
  797. },
  798. /**
  799. * onSuccess callback for check Repo URL.
  800. */
  801. checkRepoURLSuccessCallback: function (response, request, data) {
  802. var selectedStack = this.get('content.stacks').findProperty('isSelected');
  803. if (selectedStack && selectedStack.get('operatingSystems')) {
  804. var os = selectedStack.get('operatingSystems').findProperty('id', data.osId);
  805. var repo = os.get('repositories').findProperty('repoId', data.repoId);
  806. if (repo) {
  807. repo.set('validation', App.Repository.validation.OK);
  808. }
  809. }
  810. this.set('validationCnt', this.get('validationCnt') - 1);
  811. if (!this.get('validationCnt')) {
  812. this.set('content.isCheckInProgress', false);
  813. data.dfd.resolve();
  814. }
  815. },
  816. /**
  817. * onError callback for check Repo URL.
  818. */
  819. checkRepoURLErrorCallback: function (request, ajaxOptions, error, data, params) {
  820. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  821. if (selectedStack && selectedStack.get('operatingSystems')) {
  822. var os = selectedStack.get('operatingSystems').findProperty('id', params.osId);
  823. var repo = os.get('repositories').findProperty('repoId', params.repoId);
  824. if (repo) {
  825. repo.setProperties({
  826. validation: App.Repository.validation.INVALID,
  827. errorTitle: request.status + ":" + request.statusText,
  828. errorContent: $.parseJSON(request.responseText) ? $.parseJSON(request.responseText).message : ""
  829. });
  830. }
  831. }
  832. this.set('content.isCheckInProgress', false);
  833. params.dfd.reject();
  834. },
  835. loadMap: {
  836. '0': [
  837. {
  838. type: 'sync',
  839. callback: function () {
  840. this.load('cluster');
  841. }
  842. }
  843. ],
  844. '1': [
  845. {
  846. type: 'async',
  847. callback: function () {
  848. var dfd = $.Deferred();
  849. this.loadStacks().always(function() {
  850. App.router.get('clusterController').loadAmbariProperties().always(function() {
  851. dfd.resolve();
  852. });
  853. });
  854. return dfd.promise();
  855. }
  856. },
  857. {
  858. type: 'async',
  859. callback: function (stacksLoaded) {
  860. var dfd = $.Deferred();
  861. if (!stacksLoaded) {
  862. $.when.apply(this, this.loadStacksVersions()).done(function () {
  863. Em.run.later('sync', function() {
  864. dfd.resolve(stacksLoaded);
  865. }, 1000);
  866. });
  867. } else {
  868. dfd.resolve(stacksLoaded);
  869. }
  870. return dfd.promise();
  871. }
  872. }
  873. ],
  874. '2': [
  875. {
  876. type: 'sync',
  877. callback: function () {
  878. this.load('installOptions');
  879. }
  880. }
  881. ],
  882. '3': [
  883. {
  884. type: 'sync',
  885. callback: function () {
  886. this.loadConfirmedHosts();
  887. }
  888. }
  889. ],
  890. '4': [
  891. {
  892. type: 'async',
  893. callback: function () {
  894. return this.loadServices();
  895. }
  896. }
  897. ],
  898. '5': [
  899. {
  900. type: 'sync',
  901. callback: function () {
  902. this.setSkipSlavesStep(App.StackService.find().filterProperty('isSelected'), 6);
  903. this.loadMasterComponentHosts();
  904. this.loadConfirmedHosts();
  905. this.loadRecommendations();
  906. }
  907. }
  908. ],
  909. '6': [
  910. {
  911. type: 'sync',
  912. callback: function () {
  913. this.loadSlaveComponentHosts();
  914. this.loadClients();
  915. this.loadRecommendations();
  916. }
  917. }
  918. ],
  919. '7': [
  920. {
  921. type: 'async',
  922. callback: function () {
  923. this.loadServiceConfigGroups();
  924. this.loadServiceConfigProperties();
  925. this.loadCurrentHostGroups();
  926. this.loadRecommendationsConfigs();
  927. return this.loadConfigThemes();
  928. }
  929. }
  930. ]
  931. },
  932. /**
  933. * Clear all temporary data
  934. */
  935. finish: function () {
  936. this.setCurrentStep('0');
  937. this.clearStorageData();
  938. App.router.get('userSettingsController').postUserPref('show_bg', true);
  939. },
  940. /**
  941. * Save cluster provisioning state to the server
  942. * @param state cluster provisioning state
  943. */
  944. setClusterProvisioningState: function (state) {
  945. return App.ajax.send({
  946. name: 'cluster.save_provisioning_state',
  947. sender: this,
  948. data: {
  949. state: state
  950. }
  951. });
  952. },
  953. setStepsEnable: function () {
  954. for (var i = 0; i <= this.totalSteps; i++) {
  955. this.get('isStepDisabled').findProperty('step', i).set('value', i > this.get('currentStep'));
  956. }
  957. }.observes('currentStep'),
  958. setLowerStepsDisable: function (stepNo) {
  959. for (var i = 0; i < stepNo; i++) {
  960. var step = this.get('isStepDisabled').findProperty('step', i);
  961. step.set('value', true);
  962. }
  963. },
  964. /**
  965. * Compare jdk versions used for ambari and selected stack.
  966. * Validation check will fire only for non-custom jdk configuration.
  967. *
  968. * @param {Function} successCallback
  969. * @param {Function} failCallback
  970. */
  971. validateJDKVersion: function (successCallback, failCallback) {
  972. var selectedStack = App.Stack.find().findProperty('isSelected', true),
  973. currentJDKVersion = App.router.get('clusterController.ambariProperties')['java.version'],
  974. // use min as max, or max as min version, in case when some of them missed
  975. minJDKVersion = selectedStack.get('minJdkVersion') || selectedStack.get('maxJdkVersion'),
  976. maxJDKVersion = selectedStack.get('maxJdkVersion') || selectedStack.get('minJdkVersion'),
  977. t = Em.I18n.t,
  978. fCallback = failCallback || function() {},
  979. sCallback = successCallback || function() {};
  980. // Skip jdk check if min and max required version not set in stack definition.
  981. if (!minJDKVersion && !maxJDKVersion) {
  982. sCallback();
  983. return;
  984. }
  985. if (currentJDKVersion) {
  986. if (stringUtils.compareVersions(currentJDKVersion, minJDKVersion) < 0 ||
  987. stringUtils.compareVersions(maxJDKVersion, currentJDKVersion) < 0) {
  988. // checks and process only minor part for now
  989. var versionDistance = parseInt(maxJDKVersion.split('.')[1], 10) - parseInt(minJDKVersion.split('.')[1], 10);
  990. var versionsList = [minJDKVersion];
  991. for (var i = 1; i < versionDistance + 1; i++) {
  992. versionsList.push("" + minJDKVersion.split('.')[0] + '.' + (+minJDKVersion.split('.')[1] + i));
  993. }
  994. var versionsString = stringUtils.getFormattedStringFromArray(versionsList, t('or'));
  995. var popupBody = t('popup.jdkValidation.body').format(selectedStack.get('stackName') + ' ' + selectedStack.get('stackVersion'), versionsString, currentJDKVersion);
  996. App.showConfirmationPopup(sCallback, popupBody, fCallback, t('popup.jdkValidation.header'), t('common.proceedAnyway'), true);
  997. return;
  998. }
  999. }
  1000. sCallback();
  1001. }
  1002. });