installer.js 38 KB

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