installer.js 37 KB

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