installer.js 37 KB

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