step8_controller.js 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495
  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. App.WizardStep8Controller = Em.Controller.extend({
  21. name: 'wizardStep8Controller',
  22. /**
  23. * List of raw data about cluster that should be displayed
  24. * @type {Array}
  25. */
  26. rawContent: require('data/review_configs'),
  27. /**
  28. * @type {Object[]}
  29. */
  30. totalHosts: [],
  31. /**
  32. * List of data about cluster (based on formatted <code>rawContent</code>)
  33. * @type {Object[]}
  34. */
  35. clusterInfo: [],
  36. /**
  37. * List of services with components assigned to hosts
  38. * @type {Object[]}
  39. */
  40. services: [],
  41. /**
  42. * @type {Object[]}
  43. */
  44. configs: [],
  45. /**
  46. * @type {Object[]}
  47. */
  48. globals: [],
  49. /**
  50. * List of ajax-request to be executed
  51. * @type {Array}
  52. */
  53. ajaxQueue: [],
  54. /**
  55. * All configs
  56. * @type {Array}
  57. */
  58. configMapping: function(){
  59. return App.config.get('configMapping').all(true);
  60. }.property('App.config.configMapping'),
  61. /**
  62. *
  63. */
  64. slaveComponentConfig: null,
  65. /**
  66. * Should Submit button be disabled
  67. * @type {bool}
  68. */
  69. isSubmitDisabled: false,
  70. /**
  71. * Should Back button be disabled
  72. * @type {bool}
  73. */
  74. isBackBtnDisabled: false,
  75. /**
  76. * Is error appears while <code>ajaxQueue</code> executes
  77. * @type {bool}
  78. */
  79. hasErrorOccurred: false,
  80. /**
  81. * Are services installed
  82. * Used to hide Deploy Progress Bar
  83. * @type {bool}
  84. */
  85. servicesInstalled: false,
  86. /**
  87. * List of service config tags
  88. * @type {Object[]}
  89. */
  90. serviceConfigTags: [],
  91. /**
  92. * Is cluster security enabled
  93. * @type {bool}
  94. */
  95. securityEnabled: function() {
  96. return App.router.get('mainAdminSecurityController.securityEnabled');
  97. }.property('App.router.mainAdminSecurityController.securityEnabled'),
  98. /**
  99. * During page save time, we set the host overrides to the server.
  100. * The new host -> site:tag map is stored below. This will be
  101. * useful during save, to update the host's host components. Also,
  102. * it will be useful in deletion of overrides.
  103. *
  104. * Example:
  105. * {
  106. * 'hostname1': {
  107. * 'global': {
  108. * 'tagName': 'tag3187261938_hostname1',
  109. * 'map': {
  110. * 'hadoop_heapsize': '2048m'
  111. * }
  112. * }
  113. * }
  114. * }
  115. *
  116. * @see loadedHostToOverrideSiteToTagMap
  117. */
  118. savedHostToOverrideSiteToTagMap: {},
  119. /**
  120. * Selected config group
  121. * @type {Object}
  122. */
  123. selectedConfigGroup: null,
  124. /**
  125. * List of config groups
  126. * @type {Object[]}
  127. */
  128. configGroups: [],
  129. /**
  130. * List of selected but not installed services
  131. * @type {Object[]}
  132. */
  133. selectedServices: function () {
  134. return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false);
  135. }.property('content.services').cacheable(),
  136. /**
  137. * Clear current step data
  138. */
  139. clearStep: function () {
  140. this.get('services').clear();
  141. this.get('configs').clear();
  142. this.get('globals').clear();
  143. this.get('clusterInfo').clear();
  144. this.get('serviceConfigTags').clear();
  145. this.set('servicesInstalled', false);
  146. },
  147. /**
  148. * Load current step data
  149. */
  150. loadStep: function () {
  151. console.log("TRACE: Loading step8: Review Page");
  152. if (this.get('content.controllerName') != 'installerController') {
  153. App.router.get('mainAdminSecurityController').setSecurityStatus();
  154. }
  155. this.clearStep();
  156. if (this.get('content.serviceConfigProperties')) {
  157. this.formatProperties();
  158. this.loadGlobals();
  159. this.loadConfigs();
  160. }
  161. this.loadClusterInfo();
  162. this.loadServices();
  163. this.set('isSubmitDisabled', false);
  164. this.set('isBackBtnDisabled', false);
  165. },
  166. /**
  167. * replace whitespace character with coma between directories
  168. */
  169. formatProperties: function(){
  170. this.get('content.serviceConfigProperties').forEach(function(_configProperty){
  171. _configProperty.value = App.config.trimProperty(_configProperty,false);
  172. });
  173. },
  174. /**
  175. * Load global configs and remove some of them:
  176. * <ul>
  177. * <li>Unused DB properties for Hive</li>
  178. * <li>Unused DB properties for Oozie</li>
  179. * <ul>
  180. */
  181. loadGlobals: function () {
  182. var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
  183. if (globals.someProperty('name', 'hive_database')) {
  184. var hiveDb = globals.findProperty('name', 'hive_database');
  185. var hiveDbType = {name: 'hive_database_type', value: 'mysql'};
  186. if (hiveDb.value === 'New MySQL Database') {
  187. if (globals.someProperty('name', 'hive_ambari_host')) {
  188. globals.findProperty('name', 'hive_hostname').value = globals.findProperty('name', 'hive_ambari_host').value;
  189. hiveDbType.value = 'mysql';
  190. }
  191. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  192. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  193. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  194. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  195. } else if (hiveDb.value === 'Existing MySQL Database'){
  196. globals.findProperty('name', 'hive_hostname').value = globals.findProperty('name', 'hive_existing_mysql_host').value;
  197. hiveDbType.value = 'mysql';
  198. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  199. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  200. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  201. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  202. } else { //existing oracle database
  203. globals.findProperty('name', 'hive_hostname').value = globals.findProperty('name', 'hive_existing_oracle_host').value;
  204. hiveDbType.value = 'oracle';
  205. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  206. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  207. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  208. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  209. }
  210. globals.push(hiveDbType);
  211. }
  212. if (globals.someProperty('name', 'oozie_database')) {
  213. var oozieDb = globals.findProperty('name', 'oozie_database');
  214. var oozieDbType = {name:'oozie_database_type'};
  215. if (oozieDb.value === 'New Derby Database') {
  216. globals.findProperty('name', 'oozie_hostname').value = globals.findProperty('name', 'oozie_ambari_host').value;
  217. oozieDbType.value = 'derby';
  218. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  219. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  220. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  221. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  222. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  223. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  224. } else if (oozieDb.value === 'Existing MySQL Database') {
  225. globals.findProperty('name', 'oozie_hostname').value = globals.findProperty('name', 'oozie_existing_mysql_host').value;
  226. oozieDbType.value = 'mysql';
  227. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  228. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  229. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  230. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  231. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  232. } else { // existing oracle database
  233. globals.findProperty('name', 'oozie_hostname').value = globals.findProperty('name', 'oozie_existing_oracle_host').value;
  234. oozieDbType.value = 'oracle';
  235. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  236. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  237. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  238. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  239. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  240. }
  241. globals.push(oozieDbType);
  242. }
  243. this.set('globals', globals);
  244. },
  245. /**
  246. * Load all site properties
  247. */
  248. loadConfigs: function () {
  249. //storedConfigs contains custom configs as well
  250. var serviceConfigProperties = this.get('content.serviceConfigProperties').filterProperty('id', 'site property');
  251. serviceConfigProperties.forEach(function(_config){
  252. _config.value = (typeof _config.value === "boolean") ? _config.value.toString() : _config.value;
  253. });
  254. var storedConfigs = serviceConfigProperties.filterProperty('value');
  255. var mappedConfigs = App.config.excludeUnsupportedConfigs(this.get('configMapping'), this.get('selectedServices').mapProperty('serviceName'));
  256. var uiConfigs = this.loadUiSideConfigs(mappedConfigs);
  257. this.set('configs', storedConfigs.concat(uiConfigs));
  258. },
  259. /**
  260. * Load UI configs
  261. * @param {Array} configMapping
  262. * @return {Array}
  263. */
  264. loadUiSideConfigs: function (configMapping) {
  265. var uiConfig = [];
  266. var configs = configMapping.filterProperty('foreignKey', null);
  267. this.addDynamicProperties(configs);
  268. configs.forEach(function (_config) {
  269. var valueWithOverrides = this.getGlobConfigValueWithOverrides(_config.templateName, _config.value, _config.name);
  270. uiConfig.pushObject({
  271. "id": "site property",
  272. "name": _config.name,
  273. "value": valueWithOverrides.value,
  274. "filename": _config.filename,
  275. "overrides": valueWithOverrides.overrides
  276. });
  277. }, this);
  278. var dependentConfig = $.extend(true, [], configMapping.filterProperty('foreignKey'));
  279. dependentConfig.forEach(function (_config) {
  280. App.config.setConfigValue(uiConfig, this.get('content.serviceConfigProperties'), _config, this.get('globals'));
  281. uiConfig.pushObject({
  282. "id": "site property",
  283. "name": _config._name || _config.name,
  284. "value": _config.value,
  285. "filename": _config.filename
  286. });
  287. }, this);
  288. return uiConfig;
  289. },
  290. /**
  291. * Add dynamic properties to configs
  292. * @param {Array} configs
  293. */
  294. addDynamicProperties: function(configs) {
  295. var templetonHiveProperty = this.get('content.serviceConfigProperties').someProperty('name', 'templeton.hive.properties');
  296. if (!templetonHiveProperty) {
  297. configs.pushObject({
  298. "name": "templeton.hive.properties",
  299. "templateName": ["hivemetastore_host"],
  300. "foreignKey": null,
  301. "value": "hive.metastore.local=false,hive.metastore.uris=thrift://<templateName[0]>:9083,hive.metastore.sasl.enabled=yes,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse",
  302. "filename": "webhcat-site.xml"
  303. });
  304. }
  305. },
  306. /**
  307. * Format <code>content.hosts</code> from Object to Array
  308. * @returns {Array}
  309. */
  310. getRegisteredHosts: function () {
  311. var allHosts = this.get('content.hosts');
  312. var hosts = [];
  313. for (var hostName in allHosts) {
  314. if (allHosts[hostName].bootStatus == 'REGISTERED') {
  315. allHosts[hostName].hostName = allHosts[hostName].name;
  316. hosts.pushObject(allHosts[hostName]);
  317. }
  318. }
  319. return hosts;
  320. },
  321. /**
  322. * Set all site property that are derived from other puppet-variable
  323. * @param {String} templateName
  324. * @param {String} expression
  325. * @param {String} name
  326. * @return {Object}
  327. * example: <code>{
  328. * value: '...',
  329. * overrides: {
  330. * 'value1': [h1, h2],
  331. * 'value2': [h3]
  332. * }
  333. * }</code>
  334. */
  335. getGlobConfigValueWithOverrides: function (templateName, expression, name) {
  336. var express = expression.match(/<(.*?)>/g);
  337. var value = expression;
  338. if (express == null) {
  339. return { value : expression, overrides: []}; // if site property do not map any global property then return the value
  340. }
  341. var overrideHostToValue = {};
  342. express.forEach(function (_express) {
  343. //console.log("The value of template is: " + _express);
  344. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  345. if (this.get('globals').someProperty('name', templateName[index])) {
  346. //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name);
  347. var globalObj = this.get('globals').findProperty('name', templateName[index]);
  348. var globValue = globalObj.value;
  349. // Hack for templeton.zookeeper.hosts
  350. var preReplaceValue = null;
  351. if (value !== null) { // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
  352. preReplaceValue = value;
  353. value = this._replaceConfigValues(name, _express, value, globValue);
  354. }
  355. if(globalObj.overrides!=null){
  356. globalObj.overrides.forEach(function(override){
  357. var ov = override.value;
  358. var hostsArray = override.hosts;
  359. hostsArray.forEach(function(host){
  360. if(!(host in overrideHostToValue)){
  361. overrideHostToValue[host] = this._replaceConfigValues(name, _express, preReplaceValue, ov);
  362. }else{
  363. overrideHostToValue[host] = this._replaceConfigValues(name, _express, overrideHostToValue[host], ov);
  364. }
  365. }, this);
  366. }, this);
  367. }
  368. } else {
  369. /*
  370. console.log("ERROR: The variable name is: " + templateName[index]);
  371. console.log("ERROR: mapped config from configMapping file has no corresponding variable in " +
  372. "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " +
  373. "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable");
  374. */
  375. value = null;
  376. }
  377. }, this);
  378. var valueWithOverrides = {
  379. value: value,
  380. overrides: []
  381. };
  382. var overrideValueToHostMap = {};
  383. if(!jQuery.isEmptyObject(overrideHostToValue)){
  384. for(var host in overrideHostToValue){
  385. var hostVal = overrideHostToValue[host];
  386. if(!(hostVal in overrideValueToHostMap)){
  387. overrideValueToHostMap[hostVal] = [];
  388. }
  389. overrideValueToHostMap[hostVal].push(host);
  390. }
  391. }
  392. for(var val in overrideValueToHostMap){
  393. valueWithOverrides.overrides.push({
  394. value: val,
  395. hosts: overrideValueToHostMap[val]
  396. });
  397. }
  398. return valueWithOverrides;
  399. },
  400. /**
  401. * replace some values in config property
  402. * @param {string} name
  403. * @param {string} express
  404. * @param {string} value
  405. * @param {string} globValue
  406. * @return {string}
  407. * @private
  408. */
  409. _replaceConfigValues: function (name, express, value, globValue) {
  410. return value.replace(express, globValue);
  411. },
  412. /**
  413. * Load all info about cluster to <code>clusterInfo</code> variable
  414. */
  415. loadClusterInfo: function () {
  416. //Admin name
  417. var admin = this.rawContent.findProperty('config_name', 'Admin');
  418. admin.config_value = App.db.getLoginName();
  419. console.log("STEP8: the value of content cluster name: " + App.db.getLoginName());
  420. if (admin.config_value) {
  421. this.get('clusterInfo').pushObject(Ember.Object.create(admin));
  422. }
  423. // cluster name
  424. var cluster = this.rawContent.findProperty('config_name', 'cluster');
  425. cluster.config_value = this.get('content.cluster.name');
  426. console.log("STEP8: the value of content cluster name: " + this.get('content.cluster.name'));
  427. this.get('clusterInfo').pushObject(Ember.Object.create(cluster));
  428. //hosts
  429. var masterHosts = this.get('content.masterComponentHosts').mapProperty('hostName').uniq();
  430. var slaveHosts = this.get('content.slaveComponentHosts');
  431. var hostObj = [];
  432. slaveHosts.forEach(function (_hosts) {
  433. hostObj = hostObj.concat(_hosts.hosts);
  434. }, this);
  435. slaveHosts = hostObj.mapProperty('hostName').uniq();
  436. var componentHosts = masterHosts.concat(slaveHosts).uniq();
  437. var totalHosts = App.Host.find().mapProperty('hostName').concat(componentHosts).uniq();
  438. var newHostsCount = totalHosts.length - App.Host.find().content.length;
  439. this.set('totalHosts', totalHosts);
  440. var totalHostsObj = this.rawContent.findProperty('config_name', 'hosts');
  441. totalHostsObj.config_value = totalHosts.length + ' (' + newHostsCount + ' new)';
  442. this.get('clusterInfo').pushObject(Ember.Object.create(totalHostsObj));
  443. //repo
  444. if (['addHostController', 'addServiceController'].contains(this.get('content.controllerName'))) {
  445. this.loadRepoInfo();
  446. } else { // from install wizard
  447. var selectedStack = this.get('content.stacks').findProperty('isSelected', true);
  448. var allRepos = [];
  449. var supportedOs = ['redhat5', 'redhat6', 'sles11'];
  450. if (selectedStack && selectedStack.operatingSystems) {
  451. selectedStack.operatingSystems.forEach(function (os) {
  452. if (os.selected && supportedOs.contains(os.osType)) {
  453. allRepos.push(Em.Object.create({
  454. base_url: os.baseUrl,
  455. os_type: Em.I18n.t("installer.step8.repoInfo.osType." + os.osType)
  456. }));
  457. }
  458. }, this);
  459. }
  460. allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName"));
  461. this.get('clusterInfo').set('repoInfo', allRepos);
  462. }
  463. },
  464. /**
  465. * get the repositories info of HDP from server. Used only in addHost controller.
  466. */
  467. loadRepoInfo: function(){
  468. var nameVersionCombo = App.get('currentStackVersion');
  469. var stackName = nameVersionCombo.split('-')[0];
  470. var stackVersion = nameVersionCombo.split('-')[1];
  471. App.ajax.send({
  472. name: 'cluster.load_repositories',
  473. sender: this,
  474. data: {
  475. stackName: stackName,
  476. stackVersion: stackVersion
  477. },
  478. success: 'loadRepoInfoSuccessCallback',
  479. error: 'loadRepositoriesErrorCallback'
  480. });
  481. },
  482. loadRepoInfoSuccessCallback: function (data) {
  483. var allRepos = [];
  484. var supportedOs = ['redhat5', 'redhat6', 'sles11'];
  485. data.items.forEach(function (item) {
  486. var os = item.repositories[0].Repositories;
  487. if (supportedOs.contains(os.os_type)) {
  488. allRepos.push(Em.Object.create({
  489. base_url: os.base_url,
  490. os_type: Em.I18n.t("installer.step8.repoInfo.osType." + os.os_type)
  491. }));
  492. }
  493. }, this);
  494. allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName"));
  495. this.get('clusterInfo').set('repoInfo', allRepos);
  496. },
  497. loadRepoInfoErrorCallback: function(request) {
  498. console.log('Error message is: ' + request.responseText);
  499. var allRepos = [];
  500. allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName"));
  501. this.get('clusterInfo').set('repoInfo', allRepos);
  502. },
  503. /**
  504. * Load all info about services to <code>services</code> variable
  505. */
  506. loadServices: function () {
  507. var reviewService = this.rawContent.findProperty('config_name', 'services');
  508. this.get('selectedServices').forEach(function (_service) {
  509. console.log('INFO: step8: Name of the service from getService function: ' + _service.serviceName);
  510. var serviceObj = reviewService.config_value.findProperty('service_name', _service.serviceName);
  511. if (serviceObj) {
  512. serviceObj.get('service_components').forEach(function (_component) {
  513. this.assignComponentHosts(_component);
  514. }, this);
  515. this.get('services').pushObject(serviceObj);
  516. }
  517. }, this);
  518. },
  519. /**
  520. *
  521. * @param {Em.Object} component
  522. */
  523. assignComponentHosts: function (component) {
  524. var componentValue;
  525. if (component.get('customHandler')) {
  526. this[component.get('customHandler')].call(this, component);
  527. } else {
  528. if (component.get('isMaster')) {
  529. componentValue = this.get('content.masterComponentHosts')
  530. .findProperty('component', component.component_name).hostName;
  531. } else {
  532. var hostsLength = this.get('content.slaveComponentHosts')
  533. .findProperty('componentName', component.component_name)
  534. .hosts.length;
  535. componentValue = hostsLength + Em.I18n.t('installer.step8.host' + ((hostsLength > 1) ? 's' : ''));
  536. }
  537. component.set('component_value', componentValue);
  538. }
  539. },
  540. /**
  541. * Set dispalyed Hive DB value based on DB type
  542. * @param dbComponent
  543. */
  544. loadHiveDbValue: function (dbComponent) {
  545. var hiveDb = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'hive_database');
  546. if (hiveDb.value === 'New MySQL Database') {
  547. dbComponent.set('component_value', 'MySQL (New Database)');
  548. } else if(hiveDb.value === 'Existing MySQL Database'){
  549. var db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'hive_existing_mysql_database');
  550. dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
  551. } else { // existing oracle database
  552. var db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'hive_existing_oracle_database');
  553. dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
  554. }
  555. },
  556. /**
  557. * Set displayed HBase master value
  558. * @param {Object} hbaseMaster
  559. */
  560. loadHbaseMasterValue: function (hbaseMaster) {
  561. var hbaseHostName = this.get('content.masterComponentHosts').filterProperty('component', hbaseMaster.component_name);
  562. if (hbaseHostName.length == 1) {
  563. hbaseMaster.set('component_value', hbaseHostName[0].hostName);
  564. } else {
  565. hbaseMaster.set('component_value', hbaseHostName[0].hostName + Em.I18n.t('installer.step8.other').format(hbaseHostName.length - 1));
  566. }
  567. },
  568. /**
  569. * Set displayed ZooKeeper Server value
  570. * @param {Object} serverComponent
  571. */
  572. loadZkServerValue: function (serverComponent) {
  573. var zkHostNames = this.get('content.masterComponentHosts').filterProperty('component', serverComponent.component_name).length;
  574. var hostSuffix;
  575. if (zkHostNames === 1) {
  576. hostSuffix = Em.I18n.t('installer.step8.host');
  577. } else {
  578. hostSuffix = Em.I18n.t('installer.step8.hosts');
  579. }
  580. serverComponent.set('component_value', zkHostNames + ' ' + hostSuffix);
  581. },
  582. /**
  583. * Set displayed Oozie DB value based on DB type
  584. * @param {Object} dbComponent
  585. */
  586. loadOozieDbValue: function (dbComponent) {
  587. var oozieDb = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_database');
  588. if (oozieDb.value === 'New Derby Database'){
  589. var db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_derby_database');
  590. dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
  591. }/* else if (oozieDb.value === 'New MySQL Database') {
  592. dbComponent.set('component_value', 'MySQL (New Database)');
  593. } */else if(oozieDb.value === 'Existing MySQL Database'){
  594. var db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_mysql_database');
  595. dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
  596. } else { // existing oracle database
  597. var db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_oracle_database');
  598. dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
  599. }
  600. },
  601. /**
  602. * Set displayed Nagion Admin value
  603. * @param {Object} nagiosAdmin
  604. */
  605. loadNagiosAdminValue: function (nagiosAdmin) {
  606. var config = this.get('content.serviceConfigProperties');
  607. var adminLoginName = config.findProperty('name', 'nagios_web_login');
  608. var adminEmail = config.findProperty('name', 'nagios_contact');
  609. nagiosAdmin.set('component_value', adminLoginName.value + ' / (' + adminEmail.value + ')');
  610. },
  611. /**
  612. * Onclick handler for <code>next</code> button
  613. */
  614. submit: function () {
  615. if (this.get('isSubmitDisabled')) return;
  616. if ((this.get('content.controllerName') == 'addHostController') && this.get('securityEnabled')) {
  617. var self = this;
  618. App.showConfirmationPopup(function() {
  619. self.submitProceed();
  620. }, Em.I18n.t('installer.step8.securityConfirmationPopupBody'));
  621. }
  622. else {
  623. this.submitProceed();
  624. }
  625. },
  626. /**
  627. * Update configurations for installed services.
  628. *
  629. * @param {Array} configsToUpdate - configs need to update
  630. * @return {*}
  631. */
  632. updateConfigurations: function (configsToUpdate) {
  633. var configurationController = App.router.get('mainServiceInfoConfigsController');
  634. var serviceNames = configsToUpdate.mapProperty('serviceName').uniq();
  635. serviceNames.forEach(function(serviceName) {
  636. var configs = configsToUpdate.filterProperty('serviceName', serviceName);
  637. configurationController.setNewTagNames(configs);
  638. var tagName = configs.objectAt(0).newTagName;
  639. var siteConfigs = configs.filterProperty('id', 'site property');
  640. siteConfigs.mapProperty('filename').uniq().forEach(function(siteName) {
  641. var formattedConfigs = configurationController.createSiteObj(siteName.replace(".xml", ""), tagName, configs.filterProperty('filename', siteName));
  642. configurationController.doPUTClusterConfigurationSite(formattedConfigs);
  643. });
  644. });
  645. },
  646. /**
  647. * Prepare <code>ajaxQueue</code> and start to execute it
  648. */
  649. submitProceed: function() {
  650. this.set('isSubmitDisabled', true);
  651. this.set('isBackBtnDisabled', true);
  652. if (this.get('content.controllerName') == 'addHostController') {
  653. App.router.get('addHostController').setLowerStepsDisable(4);
  654. }
  655. // checkpoint the cluster status on the server so that the user can resume from where they left off
  656. switch (this.get('content.controllerName')) {
  657. case 'installerController':
  658. App.clusterStatus.setClusterStatus({
  659. clusterName: this.get('clusterName'),
  660. clusterState: 'CLUSTER_DEPLOY_PREP_2',
  661. wizardControllerName: this.get('content.controllerName'),
  662. localdb: App.db.data
  663. });
  664. break;
  665. case 'addHostController':
  666. App.clusterStatus.setClusterStatus({
  667. clusterName: this.get('clusterName'),
  668. clusterState: 'ADD_HOSTS_DEPLOY_PREP_2',
  669. wizardControllerName: this.get('content.controllerName'),
  670. localdb: App.db.data
  671. });
  672. break;
  673. case 'addServiceController':
  674. App.clusterStatus.setClusterStatus({
  675. clusterName: this.get('clusterName'),
  676. clusterState: 'ADD_SERVICES_DEPLOY_PREP_2',
  677. wizardControllerName: this.get('content.controllerName'),
  678. localdb: App.db.data
  679. });
  680. break;
  681. default:
  682. break;
  683. }
  684. // delete any existing clusters to start from a clean slate
  685. // before creating a new cluster in install wizard
  686. // TODO: modify for multi-cluster support
  687. if (this.get('content.controllerName') == 'installerController' && (!App.testMode)) {
  688. this.deleteClusters(this.getExistingClusterNames());
  689. }
  690. if (this.get('wizardController').getDBProperty('configsToUpdate')) {
  691. this.updateConfigurations(this.get('wizardController').getDBProperty('configsToUpdate'));
  692. }
  693. this.setLocalRepositories();
  694. this.createCluster();
  695. this.createSelectedServices();
  696. if (this.get('content.controllerName') !== 'addHostController') {
  697. this.createConfigurations();
  698. this.applyConfigurationsToCluster();
  699. }
  700. this.createComponents();
  701. this.registerHostsToCluster();
  702. if (App.supports.hostOverridesInstaller) {
  703. this.createConfigurationGroups();
  704. }
  705. this.createMasterHostComponents();
  706. this.createSlaveAndClientsHostComponents();
  707. this.createAdditionalHostComponents();
  708. this.doNextAjaxCall();
  709. },
  710. /**
  711. * Used in progress bar
  712. */
  713. ajaxQueueLength: function () {
  714. return this.get('ajaxQueue').length;
  715. }.property('ajaxQueue.length'),
  716. /**
  717. * Used in progress bar
  718. */
  719. ajaxQueueLeft: 0,
  720. clusterName: function () {
  721. return this.get('content.cluster.name');
  722. }.property('content.cluster.name'),
  723. clusterNames: [],
  724. /**
  725. * Get list of existing cluster names
  726. * @returns {string[]}
  727. * returns an array of existing cluster names.
  728. * returns an empty array if there are no existing clusters.
  729. */
  730. getExistingClusterNames: function () {
  731. App.ajax.send({
  732. name: 'wizard.step8.existing_cluster_names',
  733. sender: this,
  734. success: 'getExistingClusterNamesSuccessCallBack',
  735. error: 'getExistingClusterNamesErrorCallback'
  736. });
  737. return this.get('clusterNames');
  738. },
  739. /**
  740. * Save received list to <code>clusterNames</code>
  741. * @param {Object} data
  742. */
  743. getExistingClusterNamesSuccessCallBack: function (data) {
  744. var clusterNames = data.items.mapProperty('Clusters.cluster_name');
  745. console.log("Got existing cluster names: " + clusterNames);
  746. this.set('clusterNames', clusterNames);
  747. },
  748. /**
  749. * If error appears, set <code>clusterNames</code> to <code>[]</code>
  750. */
  751. getExistingClusterNamesErrorCallback: function () {
  752. console.log("Failed to get existing cluster names");
  753. this.set('clusterNames', []);
  754. },
  755. /**
  756. * Delete cluster by name
  757. * One request for one cluster!
  758. * @param {string[]} clusterNames
  759. */
  760. deleteClusters: function (clusterNames) {
  761. clusterNames.forEach(function (clusterName) {
  762. App.ajax.send({
  763. name: 'wizard.step8.delete_cluster',
  764. sender: this,
  765. data: {
  766. name: clusterName
  767. }
  768. });
  769. }, this);
  770. },
  771. /**
  772. * Updates local repositories for the Ambari server.
  773. */
  774. setLocalRepositories: function () {
  775. if (this.get('content.controllerName') !== 'installerController' || !App.supports.localRepositories) return;
  776. var self = this;
  777. this.get('content.stacks').forEach(function (stack) {
  778. stack.operatingSystems.forEach(function (os) {
  779. if (os.baseUrl !== os.originalBaseUrl) {
  780. console.log("Updating local repository URL from " + os.originalBaseUrl + " -> " + os.baseUrl + ". ", os);
  781. self.addRequestToAjaxQueue({
  782. type: 'PUT',
  783. url: App.apiPrefix + App.get('stack2VersionURL') + "/operatingSystems/" + os.osType + "/repositories/" + stack.name,
  784. data: JSON.stringify({
  785. "Repositories": {
  786. "base_url": os.baseUrl
  787. }
  788. })
  789. });
  790. }
  791. });
  792. });
  793. },
  794. /**
  795. * *******************************************************************
  796. * The following create* functions are called upon submitting Step 8.
  797. * *******************************************************************
  798. */
  799. /**
  800. * Create cluster using selected stack version
  801. * Queued request
  802. */
  803. createCluster: function () {
  804. if (this.get('content.controllerName') !== 'installerController') return;
  805. var stackVersion = (this.get('content.installOptions.localRepo')) ? App.currentStackVersion.replace(/(-\d+(\.\d)*)/ig, "Local$&") : App.currentStackVersion;
  806. this.addRequestToAjaxQueue({
  807. type: 'POST',
  808. url: App.apiPrefix + '/clusters/' + this.get('clusterName'),
  809. data: JSON.stringify({ "Clusters": {"version": stackVersion }})
  810. });
  811. },
  812. /**
  813. * Create selected to install services
  814. * Queued request
  815. * Skipped if no services where selected!
  816. */
  817. createSelectedServices: function () {
  818. var data = this.createSelectedServicesData();
  819. if (!data.length) return;
  820. this.addRequestToAjaxQueue({
  821. type: 'POST',
  822. url: App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services',
  823. data: JSON.stringify(data)
  824. });
  825. },
  826. /**
  827. * Format data for <code>createSelectedServices</code> request
  828. * @returns {Object[]}
  829. */
  830. createSelectedServicesData: function () {
  831. return this.get('selectedServices').map(function (_service) {
  832. return {"ServiceInfo": { "service_name": _service.get('serviceName') }};
  833. });
  834. },
  835. /**
  836. * Create components for selected services
  837. * Queued requests
  838. * One request for each service!
  839. */
  840. createComponents: function () {
  841. var serviceComponents = require('data/service_components');
  842. this.get('selectedServices').forEach(function (_service) {
  843. var serviceName = _service.get('serviceName');
  844. var componentsData = serviceComponents.filterProperty('service_name', serviceName).map(function (_component) {
  845. return { "ServiceComponentInfo": { "component_name": _component.component_name } };
  846. });
  847. // Service must be specified in terms of a query for creating multiple components at the same time.
  848. // See AMBARI-1018.
  849. this.addRequestToAjaxQueue({
  850. type: 'POST',
  851. url: App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services?ServiceInfo/service_name=' + serviceName,
  852. data: JSON.stringify({"components": componentsData})
  853. });
  854. }, this);
  855. },
  856. /**
  857. * Register hosts
  858. * Queued request
  859. */
  860. registerHostsToCluster: function () {
  861. var data = this.createRegisterHostData();
  862. if (!data.length) return;
  863. this.addRequestToAjaxQueue({
  864. type: 'POST',
  865. url: App.apiPrefix + '/clusters/' + this.get('clusterName') + '/hosts',
  866. data: JSON.stringify(data)
  867. });
  868. },
  869. /**
  870. * Format request-data for <code>registerHostsToCluster</code>
  871. * @returns {Object}
  872. */
  873. createRegisterHostData: function () {
  874. return this.getRegisteredHosts().filterProperty('isInstalled', false).map(function (host) {
  875. return {"Hosts": { "host_name": host.hostName}};
  876. });
  877. },
  878. /**
  879. * Register master components
  880. * @uses registerHostsToComponent
  881. */
  882. createMasterHostComponents: function() {
  883. var masterHosts = this.get('content.masterComponentHosts');
  884. masterHosts.mapProperty('component').uniq().forEach(function (component) {
  885. var hostNames = masterHosts.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName');
  886. this.registerHostsToComponent(hostNames, component);
  887. }, this);
  888. },
  889. /**
  890. * Register slave components and clients
  891. * @uses registerHostsToComponent
  892. */
  893. createSlaveAndClientsHostComponents: function() {
  894. var masterHosts = this.get('content.masterComponentHosts');
  895. var slaveHosts = this.get('content.slaveComponentHosts');
  896. var clients = this.get('content.clients');
  897. /**
  898. * Determines on which hosts client should be installed (based on availability of master components on hosts)
  899. * @type {Object}
  900. * Format:
  901. * <code>
  902. * {
  903. * CLIENT1: Em.A([MASTER1, MASTER2, ...]),
  904. * CLIENT2: Em.A([MASTER3, MASTER1, ...])
  905. * ...
  906. * }
  907. * </code>
  908. */
  909. var clientsToMasterMap = {
  910. HDFS_CLIENT: Em.A(['HBASE_MASTER', 'HBASE_REGIONSERVER', 'WEBHCAT_SERVER', 'HISTORYSERVER', 'OOZIE_SERVER']),
  911. MAPREDUCE_CLIENT: Em.A(['HIVE_SERVER', 'OOZIE_SERVER', 'NAGIOS_SERVER', 'WEBHCAT_SERVER']),
  912. OOZIE_CLIENT: Em.A(['NAGIOS_SERVER']),
  913. ZOOKEEPER_CLIENT: Em.A(['WEBHCAT_SERVER']),
  914. HIVE_CLIENT: Em.A(['WEBHCAT_SERVER','HIVE_SERVER']),
  915. HCAT: Em.A(['NAGIOS_SERVER']),
  916. YARN_CLIENT: Em.A(['NAGIOS_SERVER','HIVE_SERVER','OOZIE_SERVER','WEBHCAT_SERVER']),
  917. TEZ_CLIENT: Em.A(['NAGIOS_SERVER','HIVE_SERVER'])
  918. };
  919. slaveHosts.forEach(function (_slave) {
  920. if (_slave.componentName !== 'CLIENT') {
  921. var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName');
  922. this.registerHostsToComponent(hostNames, _slave.componentName);
  923. }
  924. else {
  925. clients.forEach(function (_client) {
  926. var hostNames = _slave.hosts.mapProperty('hostName');
  927. if (clientsToMasterMap[_client.component_name]) {
  928. clientsToMasterMap[_client.component_name].forEach(function(componentName) {
  929. masterHosts.filterProperty('component', componentName).filterProperty('isInstalled', false).forEach(function (_masterHost) {
  930. hostNames.pushObject(_masterHost.hostName);
  931. });
  932. });
  933. }
  934. hostNames = hostNames.uniq();
  935. if (_client.isInstalled) {
  936. //check whether clients are already installed on selected master hosts!!!
  937. _slave.hosts.filterProperty('isInstalled', true).mapProperty('hostName').forEach(function (host) {
  938. if (hostNames.contains(host)) {
  939. hostNames.splice(hostNames.indexOf(host), 1);
  940. }
  941. }, this);
  942. }
  943. this.registerHostsToComponent(hostNames, _client.component_name);
  944. }, this);
  945. }
  946. }, this);
  947. },
  948. /**
  949. * Register additional components
  950. * Based on availability of some services
  951. * @uses registerHostsToComponent
  952. */
  953. createAdditionalHostComponents: function() {
  954. var masterHosts = this.get('content.masterComponentHosts');
  955. // add Ganglia Monitor (Slave) to all hosts if Ganglia service is selected
  956. var gangliaService = this.get('content.services').filterProperty('isSelected', true).findProperty('serviceName', 'GANGLIA');
  957. if (gangliaService) {
  958. var hosts = this.getRegisteredHosts();
  959. if (gangliaService.get('isInstalled')) {
  960. hosts = hosts.filterProperty('isInstalled', false);
  961. }
  962. if (hosts.length) {
  963. this.registerHostsToComponent(hosts.mapProperty('hostName'), 'GANGLIA_MONITOR');
  964. }
  965. }
  966. // add MySQL Server if Hive is selected
  967. var hiveService = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).findProperty('serviceName', 'HIVE');
  968. if (hiveService) {
  969. var hiveDb = this.get('content.serviceConfigProperties').findProperty('name', 'hive_database');
  970. if(hiveDb.value == "New MySQL Database") {
  971. this.registerHostsToComponent(masterHosts.filterProperty('component', 'HIVE_SERVER').mapProperty('hostName'), 'MYSQL_SERVER');
  972. }
  973. }
  974. },
  975. /**
  976. * Register component to hosts
  977. * Queued request
  978. * @param {String[]} hostNames
  979. * @param {String} componentName
  980. */
  981. registerHostsToComponent: function (hostNames, componentName) {
  982. if (!hostNames.length) return;
  983. var queryStr = '';
  984. hostNames.forEach(function (hostName) {
  985. queryStr += 'Hosts/host_name=' + hostName + '|';
  986. });
  987. //slice off last symbol '|'
  988. queryStr = queryStr.slice(0, -1);
  989. var data = {
  990. "RequestInfo": {
  991. "query": queryStr
  992. },
  993. "Body": {
  994. "host_components": [
  995. {
  996. "HostRoles": {
  997. "component_name": componentName
  998. }
  999. }
  1000. ]
  1001. }
  1002. };
  1003. this.addRequestToAjaxQueue({
  1004. type: 'POST',
  1005. url: App.apiPrefix + '/clusters/' + this.get('clusterName') + '/hosts',
  1006. data: JSON.stringify(data)
  1007. });
  1008. },
  1009. /**
  1010. * Create config objects for cluster and services
  1011. */
  1012. createConfigurations: function () {
  1013. var self = this;
  1014. var selectedServices = this.get('selectedServices');
  1015. var coreSiteObject = this.createCoreSiteObj();
  1016. if (this.get('content.controllerName') == 'installerController') {
  1017. this.get('serviceConfigTags').pushObject(coreSiteObject);
  1018. this.get('serviceConfigTags').pushObject(this.createSiteObj('hdfs-site',false));
  1019. this.get('serviceConfigTags').pushObject(this.createLog4jObj('hdfs'));
  1020. }
  1021. var globalSiteObj = this.createGlobalSiteObj();
  1022. if (this.get('content.controllerName') == 'addServiceController') {
  1023. globalSiteObj.tag = 'version' + (new Date).getTime();
  1024. coreSiteObject.tag = 'version' + (new Date).getTime();
  1025. this.get('serviceConfigTags').pushObject(coreSiteObject);
  1026. }
  1027. this.get('serviceConfigTags').pushObject(globalSiteObj);
  1028. var objMap = {
  1029. MAPREDUCE: {site: [{filename: 'mapred-site',isXmlFile: true}], log4j: ['mapreduce']},
  1030. MAPREDUCE2: {site: [{filename:'mapred-site',isXmlFile: true}], log4j: ['mapreduce2']},
  1031. YARN: {site: [{filename:'yarn-site',isXmlFile: true},{filename:'capacity-scheduler',isXmlFile: true}], log4j: ['yarn']},
  1032. HBASE: {site: [{filename:'hbase-site',isXmlFile: true}], log4j: ['hbase']},
  1033. OOZIE: {site: [{filename:'oozie-site',isXmlFile: true}], log4j: ['oozie']},
  1034. HIVE: {site: [{filename:'hive-site',isXmlFile: true}], log4j: ['hive','hive-exec']},
  1035. WEBHCAT: {site: [{filename:'webhcat-site',isXmlFile: true}], log4j: []},
  1036. HUE: {site: [{filename:'hue-site',isXmlFile: true}], log4j: []},
  1037. PIG: {site: [], log4j: ['pig']},
  1038. FALCON: {site: [{filename:'falcon-startup.properties',isXmlFile: false},{filename:'falcon-runtime.properties',isXmlFile: false}], log4j: []},
  1039. TEZ: {site: [{filename:'tez-site',isXmlFile: true}], log4j: []},
  1040. ZOOKEEPER: {site: [], log4j: ['zookeeper']}
  1041. };
  1042. if (App.supports.capacitySchedulerUi) {
  1043. objMap['MAPREDUCE'].site.pushObjects([{filename:'capacity-scheduler',isXmlFile: true},{filename:'mapred-queue-acls',isXmlFile: true}]);
  1044. }
  1045. for(var serviceName in objMap) {
  1046. if (objMap.hasOwnProperty(serviceName)) {
  1047. if (selectedServices.someProperty('serviceName', serviceName)) {
  1048. objMap[serviceName].site.forEach(function(site) {
  1049. self.get('serviceConfigTags').pushObject(self.createSiteObj(site.filename,!site.isXmlFile));
  1050. });
  1051. objMap[serviceName].log4j.forEach(function(log4j) {
  1052. self.get('serviceConfigTags').pushObject(self.createLog4jObj(log4j));
  1053. });
  1054. }
  1055. }
  1056. }
  1057. if (selectedServices.someProperty('serviceName', 'STORM')) {
  1058. this.get('serviceConfigTags').pushObject(this.createStormSiteObj());
  1059. }
  1060. if (selectedServices.someProperty('serviceName', 'ZOOKEEPER')) {
  1061. this.get('serviceConfigTags').pushObject(this.createZooCfgObj());
  1062. }
  1063. },
  1064. /**
  1065. * Send <code>serviceConfigTags</code> to server
  1066. * Queued request
  1067. * One request for each service config tag
  1068. */
  1069. applyConfigurationsToCluster: function() {
  1070. var configData = this.get('serviceConfigTags').map(function (_serviceConfig) {
  1071. return JSON.stringify({
  1072. Clusters: {
  1073. desired_config: {
  1074. type: _serviceConfig.type,
  1075. tag: _serviceConfig.tag,
  1076. properties: _serviceConfig.properties
  1077. }
  1078. }
  1079. });
  1080. }, this).toString();
  1081. this.addRequestToAjaxQueue({
  1082. type: 'PUT',
  1083. url: App.apiPrefix + '/clusters/' + this.get('clusterName'),
  1084. data: '[' + configData + ']'
  1085. });
  1086. },
  1087. /**
  1088. * Create and update config groups
  1089. */
  1090. createConfigurationGroups: function () {
  1091. var configGroups = this.get('content.configGroups').filterProperty('isDefault', false);
  1092. var clusterName = this.get('clusterName');
  1093. var sendData = [];
  1094. var updateData = [];
  1095. var serviceConfigController = App.router.get('mainServiceInfoConfigsController');
  1096. var timeTag = (new Date).getTime();
  1097. var groupsToDelete = App.router.get(this.get('content.controllerName')).getDBProperty('groupsToDelete');
  1098. if (groupsToDelete && groupsToDelete.length > 0) {
  1099. this.removeInstalledServicesConfigurationGroups(groupsToDelete);
  1100. }
  1101. configGroups.forEach(function (configGroup) {
  1102. var groupConfigs = [];
  1103. var groupData = {
  1104. "cluster_name": clusterName,
  1105. "group_name": configGroup.name,
  1106. "tag": configGroup.service.id,
  1107. "description": configGroup.description,
  1108. "hosts": [],
  1109. "desired_configs": []
  1110. };
  1111. configGroup.hosts.forEach(function (hostName) {
  1112. groupData.hosts.push({"host_name": hostName});
  1113. });
  1114. //wrap properties into Em.Object to make them compatible with buildGroupDesiredConfigs method
  1115. configGroup.properties.forEach(function (property) {
  1116. groupConfigs.push(Em.Object.create(property));
  1117. });
  1118. groupData.desired_configs = serviceConfigController.buildGroupDesiredConfigs.call(serviceConfigController, groupConfigs, timeTag);
  1119. // check for group from installed service
  1120. if (configGroup.isForUpdate === true) {
  1121. // if group is a new one, create it
  1122. if (!configGroup.id) {
  1123. sendData.push({"ConfigGroup": groupData});
  1124. } else {
  1125. // update an existing group
  1126. groupData.id = configGroup.id;
  1127. updateData.push({"ConfigGroup": groupData});
  1128. }
  1129. } else {
  1130. sendData.push({"ConfigGroup": groupData});
  1131. }
  1132. //each group should have unique tag to prevent overriding configs from common sites
  1133. timeTag++;
  1134. }, this);
  1135. if (sendData.length > 0) {
  1136. this.applyConfigurationGroups(sendData);
  1137. }
  1138. if (updateData.length > 0) {
  1139. this.applyInstalledServicesConfigurationGroup(updateData);
  1140. }
  1141. },
  1142. /**
  1143. * Create new config groups request
  1144. * Queued request
  1145. * @param {Object[]} sendData
  1146. */
  1147. applyConfigurationGroups: function (sendData) {
  1148. this.addRequestToAjaxQueue({
  1149. type: 'POST',
  1150. url: App.apiPrefix + '/clusters/' + this.get('clusterName') + '/config_groups',
  1151. data: JSON.stringify(sendData)
  1152. });
  1153. },
  1154. /**
  1155. * Update existed config groups
  1156. * @param {Object[]} updateData
  1157. */
  1158. applyInstalledServicesConfigurationGroup: function (updateData) {
  1159. updateData.forEach(function(item) {
  1160. App.router.get('mainServiceInfoConfigsController').putConfigGroupChanges(item);
  1161. });
  1162. },
  1163. /**
  1164. * Delete selected config groups
  1165. * @param {Object[]} groupsToDelete
  1166. */
  1167. removeInstalledServicesConfigurationGroups: function(groupsToDelete) {
  1168. groupsToDelete.forEach(function(item) {
  1169. App.config.deleteConfigGroup(Em.Object.create(item));
  1170. });
  1171. },
  1172. /**
  1173. * Create Global Site object
  1174. * @returns {{type: string, tag: string, properties: {}}}
  1175. */
  1176. createGlobalSiteObj: function () {
  1177. var globalSiteProperties = {};
  1178. var globalSiteObj = this.get('globals');
  1179. var isGLUSTERFSSelected = this.get('selectedServices').someProperty('serviceName', 'GLUSTERFS');
  1180. // screen out the GLUSTERFS-specific global config entries when they are not required
  1181. if (!isGLUSTERFSSelected) {
  1182. globalSiteObj = globalSiteObj.filter(function(_config) {
  1183. return _config.name.indexOf("fs_glusterfs") < 0;
  1184. });
  1185. }
  1186. globalSiteObj.forEach(function (_globalSiteObj) {
  1187. var heapsizeException = ['hadoop_heapsize','yarn_heapsize','nodemanager_heapsize','resourcemanager_heapsize', 'apptimelineserver_heapsize'];
  1188. // do not pass any globals whose name ends with _host or _hosts
  1189. if (_globalSiteObj.isRequiredByAgent !== false) {
  1190. // append "m" to JVM memory options except for hadoop_heapsize
  1191. if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
  1192. globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value + "m";
  1193. } else {
  1194. globalSiteProperties[_globalSiteObj.name] = App.config.escapeXMLCharacters(_globalSiteObj.value);
  1195. }
  1196. }
  1197. }, this);
  1198. // we don't expose gmond_user to the user; it needs to be the same as gmetad_user
  1199. globalSiteProperties['gmond_user'] = globalSiteProperties['gmetad_user'];
  1200. return {"type": "global", "tag": "version1", "properties": globalSiteProperties};
  1201. },
  1202. /**
  1203. * Create Core Site object
  1204. * @returns {{type: string, tag: string, properties: {}}}
  1205. */
  1206. createCoreSiteObj: function () {
  1207. var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml');
  1208. var coreSiteProperties = {};
  1209. // hadoop.proxyuser.oozie.hosts needs to be skipped if oozie is not selected
  1210. var isOozieSelected = this.get('selectedServices').someProperty('serviceName', 'OOZIE');
  1211. var oozieUser = this.get('globals').someProperty('name', 'oozie_user') ? this.get('globals').findProperty('name', 'oozie_user').value : null;
  1212. var isHiveSelected = this.get('selectedServices').someProperty('serviceName', 'HIVE');
  1213. var hiveUser = this.get('globals').someProperty('name', 'hive_user') ? this.get('globals').findProperty('name', 'hive_user').value : null;
  1214. var isHcatSelected = this.get('selectedServices').someProperty('serviceName', 'WEBHCAT');
  1215. var hcatUser = this.get('globals').someProperty('name', 'hcat_user') ? this.get('globals').findProperty('name', 'hcat_user').value : null;
  1216. var isGLUSTERFSSelected = this.get('selectedServices').someProperty('serviceName', 'GLUSTERFS');
  1217. // screen out the GLUSTERFS-specific core-site.xml entries when they are not needed
  1218. if (!isGLUSTERFSSelected) {
  1219. coreSiteObj = coreSiteObj.filter(function(_config) {
  1220. return _config.name.indexOf("fs.glusterfs") < 0;
  1221. });
  1222. }
  1223. coreSiteObj.forEach(function (_coreSiteObj) {
  1224. if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
  1225. coreSiteProperties[_coreSiteObj.name] = App.config.escapeXMLCharacters(_coreSiteObj.value);
  1226. }
  1227. if (isGLUSTERFSSelected && _coreSiteObj.name == "fs.default.name") {
  1228. coreSiteProperties[_coreSiteObj.name] = this.get('globals').someProperty('name', 'fs_glusterfs_default_name') ? App.config.escapeXMLCharacters(this.get('globals').findProperty('name', 'fs_glusterfs_default_name').value) : null;
  1229. }
  1230. if (isGLUSTERFSSelected && _coreSiteObj.name == "fs.defaultFS") {
  1231. coreSiteProperties[_coreSiteObj.name] = this.get('globals').someProperty('name', 'glusterfs_defaultFS_name') ? App.config.escapeXMLCharacters(this.get('globals').findProperty('name', 'glusterfs_defaultFS_name').value) : null;
  1232. }
  1233. }, this);
  1234. return {"type": "core-site", "tag": "version1", "properties": coreSiteProperties};
  1235. },
  1236. /**
  1237. * Create siteObj for custom service with it own configs
  1238. * @param {string} site
  1239. * @param {Boolean} isNonXmlFile
  1240. * @returns {{type: string, tag: string, properties: {}}}
  1241. */
  1242. createSiteObj: function(site,isNonXmlFile) {
  1243. var properties = {};
  1244. if (!!isNonXmlFile) {
  1245. this.get('configs').filterProperty('filename', site + '.xml').forEach(function (_configProperty) {
  1246. properties[_configProperty.name] = _configProperty.value;
  1247. },this);
  1248. } else {
  1249. this.get('configs').filterProperty('filename', site + '.xml').forEach(function (_configProperty) {
  1250. properties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
  1251. },this);
  1252. }
  1253. return {"type": site, "tag": "version1", "properties": properties };
  1254. },
  1255. /**
  1256. * Create log4j object for custom service with it own configs
  1257. * @param {string} site
  1258. * @returns {{type: string, tag: string, properties: {}}}
  1259. */
  1260. createLog4jObj: function (site) {
  1261. return this.createSiteObj(site + '-log4j',true);
  1262. },
  1263. /**
  1264. * Create ZooKeeper Cfg Object
  1265. * @returns {{type: string, tag: string, properties: {}}}
  1266. */
  1267. createZooCfgObj: function () {
  1268. var configs = this.get('configs').filterProperty('filename', 'zoo.cfg');
  1269. var csProperties = {};
  1270. configs.forEach(function (_configProperty) {
  1271. csProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
  1272. }, this);
  1273. return {type: 'zoo.cfg', tag: 'version1', properties: csProperties};
  1274. },
  1275. /**
  1276. * Create site obj for Storm
  1277. * Some config-properties should be modified in custom way
  1278. * @returns {{type: string, tag: string, properties: {}}}
  1279. */
  1280. createStormSiteObj: function () {
  1281. var configs = this.get('configs').filterProperty('filename', 'storm-site.xml');
  1282. var stormProperties = {};
  1283. var specialProperties = ["storm.zookeeper.servers", "nimbus.childopts", "supervisor.childopts", "worker.childopts"];
  1284. configs.forEach(function (_configProperty) {
  1285. if (specialProperties.contains(_configProperty.name)) {
  1286. if (_configProperty.name == "storm.zookeeper.servers") {
  1287. stormProperties[_configProperty.name] = JSON.stringify(_configProperty.value).replace(/"/g, "'");
  1288. } else {
  1289. stormProperties[_configProperty.name] = JSON.stringify(_configProperty.value).replace(/"/g,"");
  1290. }
  1291. } else {
  1292. stormProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
  1293. }
  1294. }, this);
  1295. return {type: 'storm-site', tag: 'version1', properties: stormProperties};
  1296. },
  1297. /**
  1298. * Navigate to next step after all requests are sended
  1299. */
  1300. ajaxQueueFinished: function () {
  1301. console.log('everything is loaded');
  1302. App.router.send('next');
  1303. },
  1304. /**
  1305. * Do ajax-call with data in <code>ajaxQueue[0]</code> and shift <code>ajaxQueue</code>
  1306. */
  1307. doNextAjaxCall: function () {
  1308. if (this.get('ajaxBusy')) return;
  1309. var queue = this.get('ajaxQueue');
  1310. if (!queue.length) {
  1311. this.ajaxQueueFinished();
  1312. return;
  1313. }
  1314. var first = queue[0];
  1315. this.set('ajaxQueue', queue.slice(1));
  1316. this.set('ajaxQueueLeft', this.get('ajaxQueue').length);
  1317. this.set('ajaxBusy', true);
  1318. $.ajax(first);
  1319. },
  1320. /**
  1321. * We need to do a lot of ajax calls async in special order. To do this,
  1322. * generate array of ajax objects and then send requests step by step. All
  1323. * ajax objects are stored in <code>ajaxQueue</code>
  1324. *
  1325. * Each ajax-request success callback contains call of <code>doNextAjaxCall</code>
  1326. *
  1327. * @param {Object} params object with ajax-request parameters like url, type, data etc
  1328. */
  1329. addRequestToAjaxQueue: function (params) {
  1330. if (App.testMode) return;
  1331. var self = this;
  1332. params = jQuery.extend({
  1333. async: true,
  1334. dataType: 'text',
  1335. statusCode: require('data/statusCodes'),
  1336. timeout: App.timeout,
  1337. error: function () {
  1338. console.log('Step8: In Error ');
  1339. },
  1340. success: function () {
  1341. console.log("TRACE: Step8 -> In success function");
  1342. }
  1343. }, params);
  1344. var success = params.success;
  1345. var error = params.error;
  1346. params.success = function () {
  1347. if (success) {
  1348. success();
  1349. }
  1350. self.set('ajaxBusy', false);
  1351. self.doNextAjaxCall();
  1352. };
  1353. params.error = function (xhr, status, error) {
  1354. var responseText = JSON.parse(xhr.responseText);
  1355. var controller = App.router.get(App.clusterStatus.wizardControllerName);
  1356. controller.registerErrPopup(Em.I18n.t('common.error'), responseText.message);
  1357. self.set('hasErrorOccurred', true);
  1358. // an error will break the ajax call chain and allow submission again
  1359. self.set('isSubmitDisabled', false);
  1360. self.set('isBackBtnDisabled', false);
  1361. App.router.get(self.get('content.controllerName')).setStepsEnable();
  1362. self.get('ajaxQueue').clear();
  1363. self.set('ajaxBusy', false);
  1364. };
  1365. this.get('ajaxQueue').pushObject(params);
  1366. }
  1367. });