installer.js 35 KB

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