configs.js 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152
  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. require('controllers/wizard/slave_component_groups_controller');
  20. var batchUtils = require('utils/batch_scheduled_requests');
  21. App.MainServiceInfoConfigsController = Em.Controller.extend({
  22. name: 'mainServiceInfoConfigsController',
  23. isHostsConfigsPage: false,
  24. forceTransition: false,
  25. dataIsLoaded: false,
  26. stepConfigs: [], //contains all field properties that are viewed in this service
  27. selectedService: null,
  28. serviceConfigTags: null,
  29. selectedConfigGroup: null,
  30. configGroups: [],
  31. globalConfigs: [],
  32. uiConfigs: [],
  33. customConfig: [],
  34. serviceConfigsData: require('data/service_configs'),
  35. isApplyingChanges: false,
  36. // contain Service Config Property, when user proceed from Select Config Group dialog
  37. overrideToAdd: null,
  38. serviceConfigs: function () {
  39. return App.config.get('preDefinedServiceConfigs');
  40. }.property('App.config.preDefinedServiceConfigs'),
  41. customConfigs: function () {
  42. return App.config.get('preDefinedCustomConfigs');
  43. }.property('App.config.preDefinedCustomConfigs'),
  44. configMapping: function () {
  45. return App.config.get('configMapping');
  46. }.property('App.config.configMapping'),
  47. configs: function () {
  48. return App.config.get('preDefinedGlobalProperties');
  49. }.property('App.config.preDefinedGlobalProperties'),
  50. secureConfigs: function () {
  51. if (App.get('isHadoop2Stack')) {
  52. return require('data/HDP2/secure_mapping');
  53. } else {
  54. return require('data/secure_mapping');
  55. }
  56. }.property('App.isHadoop2Stack'),
  57. /**
  58. * Map, which contains relation between group and site
  59. * to upload overriden properties
  60. */
  61. loadedGroupToOverrideSiteToTagMap: {},
  62. /**
  63. * During page load time the cluster level site to tag
  64. * mapping is stored here.
  65. *
  66. * Example:
  67. * {
  68. * 'global': 'version1',
  69. * 'hdfs-site': 'version1',
  70. * 'core-site': 'version1'
  71. * }
  72. */
  73. loadedClusterSiteToTagMap: {},
  74. /**
  75. * Holds the actual base service-config server data uploaded.
  76. * This is used by the host-override mechanism to update host
  77. * specific values.
  78. */
  79. savedSiteNameToServerServiceConfigDataMap: {},
  80. isSubmitDisabled: function () {
  81. return (!(this.stepConfigs.everyProperty('errorCount', 0)) || this.get('isApplyingChanges'));
  82. }.property('stepConfigs.@each.errorCount', 'isApplyingChanges'),
  83. slaveComponentGroups: null,
  84. /**
  85. * Filter text will be located here
  86. */
  87. filter: '',
  88. /**
  89. * Dropdown menu items in filter combobox
  90. */
  91. filterColumns: function () {
  92. var result = [];
  93. for (var i = 1; i < 2; i++) {
  94. result.push(Ember.Object.create({
  95. name: this.t('common.combobox.dropdown.' + i),
  96. selected: false
  97. }));
  98. }
  99. return result;
  100. }.property(),
  101. /**
  102. * clear and set properties to default value
  103. */
  104. clearStep: function () {
  105. this.set('isInit', true);
  106. this.set('hash', null);
  107. this.set('forceTransition', false);
  108. this.set('dataIsLoaded', false);
  109. this.set('filter', '');
  110. this.get('filterColumns').setEach('selected', false);
  111. this.get('stepConfigs').clear();
  112. this.get('globalConfigs').clear();
  113. this.get('uiConfigs').clear();
  114. this.get('customConfig').clear();
  115. this.set('loadedGroupToOverrideSiteToTagMap', {});
  116. this.set('savedSiteNameToServerServiceConfigDataMap', {});
  117. if (this.get('serviceConfigTags')) {
  118. this.set('serviceConfigTags', null);
  119. }
  120. },
  121. serviceConfigProperties: function () {
  122. return App.db.getServiceConfigProperties();
  123. }.property('content'),
  124. /**
  125. * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting
  126. * Used to determine if some changes were made (when user navigates away from this page)
  127. * {String}
  128. */
  129. hash: null,
  130. /**
  131. * Is this initial config group changing
  132. * {Boolean}
  133. */
  134. isInit: true,
  135. /**
  136. * On load function
  137. */
  138. loadStep: function () {
  139. console.log("TRACE: Loading configure for service");
  140. this.clearStep();
  141. this.loadServiceConfigs();
  142. },
  143. getHash: function() {
  144. var hash = {};
  145. this.get('stepConfigs')[0].configs.forEach(function(config) {
  146. hash[config.get('name')] = {value: config.get('value'), overrides: []};
  147. if (!config.get('overrides')) return;
  148. if (!config.get('overrides.length')) return;
  149. config.get('overrides').forEach(function(override) {
  150. hash[config.get('name')].overrides.push(override.get('value'));
  151. });
  152. });
  153. return JSON.stringify(hash);
  154. },
  155. /**
  156. * Loads the actual configuration of all host components.
  157. * This helps in determining which services need a restart, and also
  158. * in showing which properties are actually applied or not.
  159. * This method also compares the actual_configs with the desired_configs
  160. * and builds a diff structure.
  161. *
  162. * Internally it calculates an array of host-components which need restart.
  163. * Example:
  164. * [
  165. * {
  166. * componentName: 'DATANODE',
  167. * serviceName: 'HDFS',
  168. * host: 'host.name',
  169. * type: 'core-site',
  170. * desiredConfigTags: {tag:'version1'},
  171. * actualConfigTags: {tag:'version4'. host_override:'version2'}
  172. * },
  173. * ...
  174. * ]
  175. *
  176. * From there it return the following restart-data for this service.
  177. * It represents the hosts, whose components need restart, and the
  178. * properties which require restart.
  179. *
  180. * {
  181. * hostAndHostComponents: {
  182. * 'hostname1': {
  183. * 'DATANODE': {
  184. * 'property1': 'value1',
  185. * 'property2': 'value2'
  186. * },
  187. * 'TASKTRACKER': {
  188. * 'prop1': 'val1'
  189. * }
  190. * },
  191. * 'hostname6': {
  192. * 'ZOOKEEPER': {
  193. * 'property1': 'value3'
  194. * }
  195. * }
  196. * },
  197. * propertyToHostAndComponent: {
  198. * 'property1': {
  199. * 'hostname1': ['DATANODE'],
  200. * 'hostname6': ['ZOOKEEPER']
  201. * },
  202. * 'property2': {
  203. * 'hostname1': ['DATANODE']
  204. * },
  205. * 'prop1': {
  206. * 'hostname1': ['TASKTRACKER']
  207. * }
  208. * }
  209. * }
  210. */
  211. loadActualConfigsAndCalculateRestarts: function () {
  212. var restartData = {
  213. hostAndHostComponents: {},
  214. propertyToHostAndComponent: {}
  215. };
  216. console.log("loadActualConfigsAndCalculateRestarts(): Restart data = ", restartData);
  217. return restartData;
  218. },
  219. /**
  220. * Loads service configurations
  221. */
  222. loadServiceConfigs: function () {
  223. App.ajax.send({
  224. name: 'config.tags_and_groups',
  225. sender: this,
  226. data: {
  227. serviceName: this.get('content.serviceName'),
  228. serviceConfigsDef: this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName'))
  229. },
  230. success: 'loadServiceTagsSuccess'
  231. });
  232. },
  233. loadServiceTagsSuccess: function (data, opt, params) {
  234. var serviceConfigsDef = params.serviceConfigsDef;
  235. var serviceName = this.get('content.serviceName');
  236. console.debug("loadServiceConfigs(): data=", data);
  237. // Create default configuration group
  238. var defaultConfigGroupHosts = App.Host.find().mapProperty('hostName');
  239. var selectedConfigGroup;
  240. var siteToTagMap = {};
  241. serviceConfigsDef.sites.forEach(function(siteName){
  242. if(data.Clusters.desired_configs[siteName]){
  243. siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
  244. } else {
  245. siteToTagMap[siteName] = 'version1';
  246. }
  247. }, this);
  248. this.loadedClusterSiteToTagMap = siteToTagMap;
  249. //parse loaded config groups
  250. if (App.supports.hostOverrides) {
  251. var configGroups = [];
  252. if (data.config_groups.length) {
  253. data.config_groups.forEach(function (item) {
  254. item = item.ConfigGroup;
  255. if (item.tag === this.get('content.serviceName')) {
  256. var groupHosts = item.hosts.mapProperty('host_name');
  257. var newConfigGroup = App.ConfigGroup.create({
  258. id: item.id,
  259. name: item.group_name,
  260. description: item.description,
  261. isDefault: false,
  262. parentConfigGroup: null,
  263. service: App.Service.find().findProperty('serviceName', item.tag),
  264. hosts: groupHosts,
  265. configSiteTags: []
  266. });
  267. groupHosts.forEach(function (host) {
  268. defaultConfigGroupHosts = defaultConfigGroupHosts.without(host);
  269. }, this);
  270. item.desired_configs.forEach(function (config) {
  271. newConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({
  272. site: config.type,
  273. tag: config.tag
  274. }));
  275. }, this);
  276. // select default selected group for hosts page
  277. if (!selectedConfigGroup && this.get('isHostsConfigsPage') && newConfigGroup.get('hosts').contains(this.get('host.hostName')) && this.get('content.serviceName') === item.tag) {
  278. selectedConfigGroup = newConfigGroup;
  279. }
  280. configGroups.push(newConfigGroup);
  281. }
  282. }, this);
  283. }
  284. this.set('configGroups', configGroups);
  285. }
  286. var defaultConfigGroup = App.ConfigGroup.create({
  287. name: App.Service.DisplayNames[serviceName] + " Default",
  288. description: "Default cluster level " + serviceName + " configuration",
  289. isDefault: true,
  290. hosts: defaultConfigGroupHosts,
  291. parentConfigGroup: null,
  292. service: this.get('content'),
  293. serviceName: serviceName,
  294. configSiteTags: []
  295. });
  296. if (!selectedConfigGroup) {
  297. selectedConfigGroup = defaultConfigGroup;
  298. }
  299. this.get('configGroups').sort(function(configGroupA, configGroupB){
  300. return (configGroupA.name > configGroupB.name);
  301. });
  302. this.get('configGroups').unshift(defaultConfigGroup);
  303. this.set('selectedConfigGroup', selectedConfigGroup);
  304. },
  305. onConfigGroupChange: function () {
  306. this.get('stepConfigs').clear();
  307. var selectedConfigGroup = this.get('selectedConfigGroup');
  308. var serviceName = this.get('content.serviceName');
  309. //STEP 1: handle tags from JSON data for host overrides
  310. this.loadedGroupToOverrideSiteToTagMap = {};
  311. if (App.supports.hostOverrides) {
  312. var configGroupsWithOverrides = selectedConfigGroup.get('isDefault') && !this.get('isHostsConfigsPage') ? this.get('configGroups') : [selectedConfigGroup];
  313. configGroupsWithOverrides.forEach(function (item) {
  314. var groupName = item.get('name');
  315. this.loadedGroupToOverrideSiteToTagMap[groupName] = {};
  316. item.get('configSiteTags').forEach(function (siteTag) {
  317. var site = siteTag.get('site');
  318. this.loadedGroupToOverrideSiteToTagMap[groupName][site] = siteTag.get('tag');
  319. }, this);
  320. }, this);
  321. }
  322. //STEP 2: Create an array of objects defining tag names to be polled and new tag names to be set after submit
  323. this.setServiceConfigTags(this.loadedClusterSiteToTagMap);
  324. //STEP 3: Load advanced configs from server
  325. var advancedConfigs = [];
  326. App.config.loadAdvancedConfig(serviceName, function (properties) {
  327. advancedConfigs.pushObjects(properties);
  328. }, true);
  329. //STEP 4: Load on-site config by service from server
  330. var configGroups = App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags'));
  331. //STEP 5: Merge global and on-site configs with pre-defined
  332. var configSet = App.config.mergePreDefinedWithLoaded(configGroups, advancedConfigs, this.get('serviceConfigTags'), serviceName);
  333. configSet = App.config.syncOrderWithPredefined(configSet);
  334. //var serviceConfigs = this.getSitesConfigProperties(advancedConfigs);
  335. var configs = configSet.configs;
  336. //put global configs into globalConfigs to save them separately
  337. this.set('globalConfigs', configSet.globalConfigs);
  338. //STEP 6: add advanced configs
  339. //App.config.addAdvancedConfigs(configs, advancedConfigs, serviceName);
  340. //STEP 7: add custom configs
  341. App.config.addCustomConfigs(configs);
  342. //put properties from capacity-scheduler.xml into one config with textarea view
  343. if (this.get('content.serviceName') === 'YARN' && !App.supports.capacitySchedulerUi) {
  344. configs = App.config.fileConfigsIntoTextarea(configs, 'capacity-scheduler.xml');
  345. }
  346. //STEP 8: add configs as names of host components
  347. this.addHostNamesToGlobalConfig();
  348. var allConfigs = this.get('globalConfigs').concat(configs);
  349. //STEP 9: Load and add overriden configs of group
  350. App.config.loadServiceConfigGroupOverrides(allConfigs, this.loadedGroupToOverrideSiteToTagMap, this.get('configGroups'));
  351. var restartData = this.loadActualConfigsAndCalculateRestarts();
  352. //STEP 10: creation of serviceConfig object which contains configs for current service
  353. var serviceConfig = App.config.createServiceConfig(serviceName);
  354. //STEP11: Make SecondaryNameNode invisible on enabling namenode HA
  355. if (serviceConfig.get('serviceName') === 'HDFS') {
  356. App.config.OnNnHAHideSnn(serviceConfig);
  357. }
  358. this.checkForRestart(serviceConfig, restartData);
  359. if (serviceName || serviceConfig.serviceName === 'MISC') {
  360. //STEP 11: render configs and wrap each in ServiceConfigProperty object
  361. this.setRecommendedDefaults(advancedConfigs);
  362. this.loadConfigs(configs, serviceConfig, restartData);
  363. this.checkOverrideProperty(serviceConfig);
  364. this.get('stepConfigs').pushObject(serviceConfig);
  365. }
  366. this.set('selectedService', this.get('stepConfigs').objectAt(0));
  367. this.checkForSecureConfig(this.get('selectedService'));
  368. this.set('dataIsLoaded', true);
  369. this.set('hash', this.getHash());
  370. this.set('isInit', false);
  371. }.observes('selectedConfigGroup'),
  372. /**
  373. * Changes format from Object to Array
  374. *
  375. * {
  376. * 'core-site': 'version1',
  377. * 'hdfs-site': 'version1',
  378. * 'global': 'version2',
  379. * ...
  380. * }
  381. *
  382. * to
  383. *
  384. * [
  385. * {
  386. * siteName: 'core-site',
  387. * tagName: 'version1',
  388. * newTageName: null
  389. * },
  390. * ...
  391. * ]
  392. *
  393. * set tagnames for configuration of the *-site.xml
  394. */
  395. setServiceConfigTags: function (desiredConfigsSiteTags) {
  396. console.debug("setServiceConfigTags(): Trying to set ", desiredConfigsSiteTags);
  397. var newServiceConfigTags = [];
  398. for (var index in desiredConfigsSiteTags) {
  399. newServiceConfigTags.pushObject({
  400. siteName: index,
  401. tagName: desiredConfigsSiteTags[index],
  402. newTagName: null
  403. }, this);
  404. }
  405. console.debug("setServiceConfigTags(): Setting 'serviceConfigTags' to ", newServiceConfigTags);
  406. this.set('serviceConfigTags', newServiceConfigTags);
  407. },
  408. /**
  409. * check whether host component must be restarted
  410. * @param serviceConfig
  411. * @param restartData
  412. */
  413. checkForRestart: function (serviceConfig, restartData) {
  414. var hostsCount = 0;
  415. var hostComponentCount = 0;
  416. var restartHosts = Ember.A([]);
  417. if (restartData != null && restartData.hostAndHostComponents != null && !jQuery.isEmptyObject(restartData.hostAndHostComponents)) {
  418. serviceConfig.set('restartRequired', true);
  419. for (var host in restartData.hostAndHostComponents) {
  420. hostsCount++;
  421. var componentsArray = Ember.A([]);
  422. for (var component in restartData.hostAndHostComponents[host]) {
  423. componentsArray.push(Ember.Object.create({name: App.format.role(component)}));
  424. hostComponentCount++;
  425. }
  426. var hostObj = App.Host.find(host);
  427. restartHosts.push(Ember.Object.create({hostData: hostObj, components: componentsArray}))
  428. }
  429. serviceConfig.set('restartRequiredHostsAndComponents', restartHosts);
  430. serviceConfig.set('restartRequiredMessage', 'Service needs ' + hostComponentCount + ' components on ' + hostsCount + ' hosts to be restarted.')
  431. }
  432. },
  433. /**
  434. * check whether the config property is a security related knob
  435. * @param serviceConfig
  436. */
  437. checkForSecureConfig: function (serviceConfig) {
  438. serviceConfig.get('configs').forEach(function (_config) {
  439. this.get('secureConfigs').forEach(function (_secureConfig) {
  440. if (_config.get('name') === _secureConfig.name) {
  441. _config.set('isSecureConfig', true);
  442. }
  443. }, this)
  444. }, this)
  445. },
  446. /**
  447. * Get info about hosts and host components to configDefaultsProviders
  448. * @returns {{masterComponentHosts: Array, slaveComponentHosts: Array, hosts: {}}}
  449. */
  450. getInfoForDefaults: function() {
  451. var slaveComponentHosts = [];
  452. var slaves = App.HostComponent.find().filterProperty('isSlave', true).map(function(item) {
  453. return Em.Object.create({
  454. host: item.get('host.hostName'),
  455. componentName: item.get('componentName')
  456. });
  457. });
  458. slaves.forEach(function(slave) {
  459. var s = slaveComponentHosts.findProperty('componentName', slave.componentName);
  460. if (s) {
  461. s.hosts.push({hostName: slave.host});
  462. }
  463. else {
  464. slaveComponentHosts.push({
  465. componentName: slave.get('componentName'),
  466. hosts: [{hostName: slave.host}]
  467. });
  468. }
  469. });
  470. var masterComponentHosts = App.HostComponent.find().filterProperty('isMaster', true).map(function(item) {
  471. return {
  472. component: item.get('componentName'),
  473. serviceId: item.get('service.serviceName'),
  474. host: item.get('host.hostName')
  475. }
  476. });
  477. var hosts = {};
  478. App.Host.find().map(function(host) {
  479. hosts[host.get('hostName')] = {
  480. name: host.get('hostName'),
  481. cpu: host.get('cpu'),
  482. memory: host.get('memory'),
  483. disk_info: host.get('diskInfo')
  484. };
  485. });
  486. return {
  487. masterComponentHosts: masterComponentHosts,
  488. slaveComponentHosts: slaveComponentHosts,
  489. hosts: hosts
  490. };
  491. },
  492. /**
  493. * Load child components to service config object
  494. * @param {Array} configs - array of configs
  495. * @param {Object} componentConfig - component config object
  496. * @param {Object} restartData
  497. * {
  498. * {Object} hostAndHostComponents,
  499. * {Object} propertyToHostAndComponent
  500. * }
  501. * @method loadConfigs
  502. */
  503. loadConfigs: function(configs, componentConfig, restartData) {
  504. var serviceConfigsData = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
  505. var defaultGroupSelected = this.get('selectedConfigGroup.isDefault');
  506. configs.forEach(function (_serviceConfigProperty) {
  507. var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, restartData, serviceConfigsData);
  508. componentConfig.configs.pushObject(serviceConfigProperty);
  509. serviceConfigProperty.validate();
  510. }, this);
  511. },
  512. /**
  513. * create {Em.Object}service_cfg_property based on {Object}_serviceConfigProperty and additional info
  514. * @param {Object} _serviceConfigProperty - config object
  515. * @param {Boolean} defaultGroupSelected - true if selected cfg group is default
  516. * @param {Object} restartData
  517. * {
  518. * {Object} hostAndHostComponents,
  519. * {Object} propertyToHostAndComponent
  520. * }
  521. * @param {Object} serviceConfigsData - service cfg object
  522. * @returns {Ember.Object|undefined}
  523. * @method createConfigProperty
  524. */
  525. createConfigProperty: function(_serviceConfigProperty, defaultGroupSelected, restartData, serviceConfigsData) {
  526. console.log("config", _serviceConfigProperty);
  527. if (!_serviceConfigProperty) return;
  528. var overrides = _serviceConfigProperty.overrides;
  529. // we will populate the override properties below
  530. _serviceConfigProperty.overrides = null;
  531. _serviceConfigProperty.isOverridable = Em.isNone(_serviceConfigProperty.isOverridable) ? true : _serviceConfigProperty.isOverridable;
  532. var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
  533. this.setValueForCheckBox(serviceConfigProperty);
  534. this.setRestartInfo(restartData, serviceConfigProperty);
  535. this.setValidator(serviceConfigProperty, serviceConfigsData);
  536. this.setValuesForOverrides(overrides, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected);
  537. this.setEditability(serviceConfigProperty, defaultGroupSelected);
  538. return serviceConfigProperty;
  539. },
  540. /**
  541. * trigger addOverrideProperty
  542. * @param {Object} componentConfig
  543. * @method checkOverrideProperty
  544. */
  545. checkOverrideProperty: function(componentConfig) {
  546. var overrideToAdd = this.get('overrideToAdd');
  547. if (overrideToAdd) {
  548. overrideToAdd = componentConfig.configs.findProperty('name', overrideToAdd.name);
  549. if (overrideToAdd) {
  550. this.addOverrideProperty(overrideToAdd);
  551. this.set('overrideToAdd', null);
  552. }
  553. }
  554. },
  555. /**
  556. * set recommended defaults for advanced configs for current service
  557. * @param {Array} advancedConfigs
  558. * @mrethod setRecommendedDefaults
  559. */
  560. setRecommendedDefaults: function (advancedConfigs) {
  561. var s = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
  562. var localDB = this.getInfoForDefaults();
  563. var recommendedDefaults = {};
  564. if (s.defaultsProviders) {
  565. s.defaultsProviders.forEach(function (defaultsProvider) {
  566. var d = defaultsProvider.getDefaults(localDB);
  567. for (var name in d) {
  568. if (!!d[name]) {
  569. recommendedDefaults[name] = d[name];
  570. } else {
  571. var defaultValueFromStack = advancedConfigs.findProperty('name', name);
  572. // If property default value is not declared on client, fetch it from stack definition
  573. // If it's not declared with any valid value in both server stack and client, then js reference error is expected to be thrown
  574. recommendedDefaults[name] = defaultValueFromStack.value
  575. }
  576. }
  577. });
  578. }
  579. if (s.configsValidator) {
  580. s.configsValidator.set('recommendedDefaults', recommendedDefaults);
  581. }
  582. },
  583. /**
  584. * set isEditable property of config for admin
  585. * if default cfg group and not on the host config page
  586. * @param {Ember.Object} serviceConfigProperty
  587. * @param {Boolean} defaultGroupSelected
  588. * @method setEditability
  589. */
  590. setEditability: function (serviceConfigProperty, defaultGroupSelected) {
  591. serviceConfigProperty.set('isEditable', false);
  592. if (App.get('isAdmin') && defaultGroupSelected && !this.get('isHostsConfigsPage')) {
  593. serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
  594. }
  595. },
  596. /**
  597. * set serviceValidator for config property
  598. * hide properties for other services
  599. * @param {Ember.Object} serviceConfigProperty
  600. * @param {Object} serviceConfigsData
  601. * @method setValidator
  602. */
  603. setValidator: function(serviceConfigProperty, serviceConfigsData) {
  604. if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
  605. if (serviceConfigsData.configsValidator) {
  606. for (var validatorName in serviceConfigsData.configsValidator.get('configValidators')) {
  607. if (serviceConfigProperty.get("name") == validatorName) {
  608. serviceConfigProperty.set('serviceValidator', serviceConfigsData.configsValidator);
  609. }
  610. }
  611. }
  612. console.log("config result", serviceConfigProperty);
  613. } else {
  614. serviceConfigProperty.set('isVisible', false);
  615. }
  616. },
  617. /**
  618. * generate restart mesage with components and host to restart
  619. * @param {Object} restartData
  620. * {
  621. * {Object} hostAndHostComponents,
  622. * {Object} propertyToHostAndComponent
  623. * }
  624. * @param {Ember.Object} serviceConfigProperty
  625. * @method setRestartInfo
  626. */
  627. setRestartInfo: function(restartData, serviceConfigProperty) {
  628. var propertyName = serviceConfigProperty.get('name');
  629. if (restartData != null && propertyName in restartData.propertyToHostAndComponent) {
  630. serviceConfigProperty.set('isRestartRequired', true);
  631. var message = '<ul>';
  632. for (var host in restartData.propertyToHostAndComponent[propertyName]) {
  633. var appHost = App.Host.find(host);
  634. message += "<li>" + appHost.get('publicHostName');
  635. message += "<ul>";
  636. restartData.propertyToHostAndComponent[propertyName][host].forEach(function (comp) {
  637. message += "<li>" + App.format.role(comp) + "</li>"
  638. });
  639. message += "</ul></li>";
  640. }
  641. message += "</ul>";
  642. serviceConfigProperty.set('restartRequiredMessage', message);
  643. }
  644. },
  645. /**
  646. * set override values
  647. * @param overrides
  648. * @param _serviceConfigProperty
  649. * @param serviceConfigProperty
  650. * @param defaultGroupSelected
  651. */
  652. setValuesForOverrides: function (overrides, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) {
  653. if (Em.isNone(overrides)) return;
  654. overrides.forEach(function (override) {
  655. var newSCP = this.createNewSCP(override, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected);
  656. var parentOverridesArray = serviceConfigProperty.get('overrides');
  657. if (parentOverridesArray == null) {
  658. parentOverridesArray = Em.A([]);
  659. serviceConfigProperty.set('overrides', parentOverridesArray);
  660. }
  661. parentOverridesArray.pushObject(newSCP);
  662. console.debug("createOverrideProperty(): Added:", newSCP, " to main-property:", serviceConfigProperty)
  663. }, this);
  664. },
  665. /**
  666. * create new overiden property and set approperiate fields
  667. * @param override
  668. * @param _serviceConfigProperty
  669. * @param serviceConfigProperty
  670. * @param defaultGroupSelected
  671. * @returns {*}
  672. */
  673. createNewSCP: function(override, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) {
  674. var newSCP = App.ServiceConfigProperty.create(_serviceConfigProperty);
  675. newSCP.set('value', override.value);
  676. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  677. newSCP.set('parentSCP', serviceConfigProperty);
  678. if (App.supports.hostOverrides && defaultGroupSelected) {
  679. newSCP.set('group', override.group);
  680. newSCP.set('isEditable', false);
  681. }
  682. return newSCP;
  683. },
  684. /**
  685. * convert string values to boolean for checkboxes
  686. * @param {Ember.Object} serviceConfigProperty
  687. */
  688. setValueForCheckBox: function(serviceConfigProperty) {
  689. if (serviceConfigProperty.get("displayType") == 'checkbox') {
  690. switch (serviceConfigProperty.get("value")) {
  691. case 'true':
  692. serviceConfigProperty.set("value", true);
  693. serviceConfigProperty.set("defaultValue", true);
  694. break;
  695. case 'false':
  696. serviceConfigProperty.set("value", false);
  697. serviceConfigProperty.set("defaultValue", false);
  698. break;
  699. }
  700. }
  701. },
  702. /**
  703. * Determines which host components are running on each host.
  704. * @param {Array} services
  705. * @param {String} status 'running' or 'unknown'
  706. * @return Returned in the following format:
  707. * {
  708. * runningHosts: {
  709. * 'hostname1': 'NameNode, DataNode, JobTracker',
  710. * 'hostname2': 'DataNode',
  711. * },
  712. * runningComponentCount: 5
  713. * }
  714. */
  715. getHostComponentsByStatus: function (services, status) {
  716. var hosts = [];
  717. var componentCount = 0;
  718. var hostToIndexMap = {};
  719. services.forEach(function (service) {
  720. var hostComponents = service.get('hostComponents').filterProperty('workStatus', status);
  721. if (hostComponents != null) {
  722. hostComponents.forEach(function (hc) {
  723. var hostName = hc.get('host.publicHostName');
  724. var componentName = hc.get('displayName');
  725. componentCount++;
  726. if (!(hostName in hostToIndexMap)) {
  727. hosts.push({
  728. name: hostName,
  729. components: ""
  730. });
  731. hostToIndexMap[hostName] = hosts.length - 1;
  732. }
  733. var hostObj = hosts[hostToIndexMap[hostName]];
  734. if (hostObj.components.length > 0)
  735. hostObj.components += ", " + componentName;
  736. else
  737. hostObj.components += componentName;
  738. });
  739. hosts.sort(function (a, b) {
  740. return a.name.localeCompare(b.name);
  741. });
  742. }
  743. });
  744. return {
  745. hosts: hosts,
  746. componentCount: componentCount
  747. };
  748. },
  749. /**
  750. * open popup with appropriate message
  751. */
  752. restartServicePopup: function (event) {
  753. if (this.get("isSubmitDisabled")) {
  754. return;
  755. }
  756. var header;
  757. var message;
  758. var messageClass;
  759. var hasUnknown = false;
  760. var value;
  761. var flag = false;
  762. var runningHosts = null;
  763. var runningComponentCount = 0;
  764. var unknownHosts = null;
  765. var unknownComponentCount = 0;
  766. var dfd = $.Deferred();
  767. var self = this;
  768. var serviceName = this.get('content.serviceName');
  769. var displayName = this.get('content.displayName');
  770. if (App.supports.hostOverrides ||
  771. (serviceName !== 'HDFS' && this.get('content.isStopped') === true) ||
  772. ((serviceName === 'HDFS') && this.get('content.isStopped') === true && (!App.Service.find().someProperty('id', 'MAPREDUCE') || App.Service.find('MAPREDUCE').get('isStopped')))) {
  773. // warn the user if any service directories are being changed
  774. var dirChanged = false;
  775. if (serviceName === 'HDFS') {
  776. var hdfsConfigs = self.get('stepConfigs').findProperty('serviceName', 'HDFS').get('configs');
  777. if (App.get('isHadoop2Stack')) {
  778. if (
  779. hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir').get('isNotDefaultValue') ||
  780. hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir').get('isNotDefaultValue') ||
  781. hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir').get('isNotDefaultValue')
  782. ) {
  783. dirChanged = true;
  784. }
  785. } else {
  786. if (
  787. hdfsConfigs.findProperty('name', 'dfs.name.dir').get('isNotDefaultValue') ||
  788. hdfsConfigs.findProperty('name', 'fs.checkpoint.dir').get('isNotDefaultValue') ||
  789. hdfsConfigs.findProperty('name', 'dfs.data.dir').get('isNotDefaultValue')
  790. ) {
  791. dirChanged = true;
  792. }
  793. }
  794. } else if (serviceName === 'MAPREDUCE') {
  795. var mapredConfigs = self.get('stepConfigs').findProperty('serviceName', 'MAPREDUCE').get('configs');
  796. if (
  797. mapredConfigs.findProperty('name', 'mapred.local.dir').get('isNotDefaultValue') ||
  798. mapredConfigs.findProperty('name', 'mapred.system.dir').get('isNotDefaultValue')
  799. ) {
  800. dirChanged = true;
  801. }
  802. }
  803. if (dirChanged) {
  804. App.showConfirmationPopup(function () {
  805. dfd.resolve();
  806. }, Em.I18n.t('services.service.config.confirmDirectoryChange').format(displayName));
  807. } else {
  808. dfd.resolve();
  809. }
  810. dfd.done(function () {
  811. var result = self.saveServiceConfigProperties();
  812. App.router.get('clusterController').updateClusterData();
  813. App.router.get('updateController').updateComponentConfig(function(){});
  814. flag = result.flag;
  815. if (result.flag === true) {
  816. header = Em.I18n.t('services.service.config.saved');
  817. message = Em.I18n.t('services.service.config.saved.message');
  818. messageClass = 'alert alert-success';
  819. // warn the user if any of the components are in UNKNOWN state
  820. var uhc;
  821. if (self.get('content.serviceName') !== 'HDFS' || (self.get('content.serviceName') === 'HDFS' && !App.Service.find().someProperty('id', 'MAPREDUCE'))) {
  822. uhc = self.getHostComponentsByStatus([self.get('content')], App.HostComponentStatus.unknown);
  823. } else {
  824. uhc = self.getHostComponentsByStatus([self.get('content'), App.Service.find('MAPREDUCE')], App.HostComponentStatus.unknown);
  825. }
  826. unknownHosts = uhc.hosts;
  827. unknownComponentCount = uhc.componentCount;
  828. } else {
  829. header = Em.I18n.t('common.failure');
  830. message = result.message;
  831. messageClass = 'alert alert-error';
  832. value = result.value;
  833. }
  834. });
  835. } else {
  836. var rhc;
  837. if (this.get('content.serviceName') !== 'HDFS' || (this.get('content.serviceName') === 'HDFS' && !App.Service.find().someProperty('id', 'MAPREDUCE'))) {
  838. rhc = this.getHostComponentsByStatus([this.get('content')], App.HostComponentStatus.started);
  839. header = Em.I18n.t('services.service.config.notSaved');
  840. message = Em.I18n.t('services.service.config.msgServiceStop');
  841. } else {
  842. rhc = this.getHostComponentsByStatus([this.get('content'), App.Service.find('MAPREDUCE')], App.HostComponentStatus.started);
  843. header = Em.I18n.t('services.service.config.notSaved');
  844. message = Em.I18n.t('services.service.config.msgHDFSMapRServiceStop');
  845. }
  846. messageClass = 'alert alert-error';
  847. runningHosts = rhc.hosts;
  848. runningComponentCount = rhc.componentCount;
  849. dfd.resolve();
  850. }
  851. dfd.done(function () {
  852. App.ModalPopup.show({
  853. header: header,
  854. primary: Em.I18n.t('ok'),
  855. secondary: null,
  856. onPrimary: function () {
  857. this.hide();
  858. if (flag) {
  859. self.loadStep();
  860. }
  861. },
  862. bodyClass: Ember.View.extend({
  863. flag: flag,
  864. message: message,
  865. messageClass: messageClass,
  866. runningHosts: runningHosts,
  867. runningComponentCount: runningComponentCount,
  868. unknownHosts: unknownHosts,
  869. unknownComponentCount: unknownComponentCount,
  870. siteProperties: value,
  871. getDisplayMessage: function () {
  872. var displayMsg = [];
  873. var siteProperties = this.get('siteProperties');
  874. if (siteProperties) {
  875. siteProperties.forEach(function (_siteProperty) {
  876. var displayProperty = _siteProperty.siteProperty;
  877. var displayNames = _siteProperty.displayNames;
  878. /////////
  879. if (displayNames && displayNames.length) {
  880. if (displayNames.length === 1) {
  881. displayMsg.push(displayProperty + Em.I18n.t('as') + displayNames[0]);
  882. } else {
  883. var name;
  884. displayNames.forEach(function (_name, index) {
  885. if (index === 0) {
  886. name = _name;
  887. } else if (index === siteProperties.length - 1) {
  888. name = name + Em.I18n.t('and') + _name;
  889. } else {
  890. name = name + ', ' + _name;
  891. }
  892. }, this);
  893. displayMsg.push(displayProperty + Em.I18n.t('as') + name);
  894. }
  895. } else {
  896. displayMsg.push(displayProperty);
  897. }
  898. }, this);
  899. }
  900. return displayMsg;
  901. }.property('siteProperties'),
  902. runningHostsMessage: function () {
  903. return Em.I18n.t('services.service.config.stopService.runningHostComponents').format(this.get('runningComponentCount'), this.get('runningHosts.length'));
  904. }.property('runningComponentCount', 'runningHosts.length'),
  905. unknownHostsMessage: function () {
  906. return Em.I18n.t('services.service.config.stopService.unknownHostComponents').format(this.get('unknownComponentCount'), this.get('unknownHosts.length'));
  907. }.property('unknownComponentCount', 'unknownHosts.length'),
  908. templateName: require('templates/main/service/info/configs_save_popup')
  909. })
  910. })
  911. });
  912. },
  913. /**
  914. * Save config properties
  915. */
  916. saveServiceConfigProperties: function () {
  917. var result = {
  918. flag: false,
  919. message: null,
  920. value: null
  921. };
  922. var selectedConfigGroup = this.get('selectedConfigGroup');
  923. var configs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
  924. if (selectedConfigGroup.get('isDefault')) {
  925. this.saveGlobalConfigs(configs);
  926. if (this.get('content.serviceName') === 'YARN' && !App.supports.capacitySchedulerUi) {
  927. configs = App.config.textareaIntoFileConfigs(configs, 'capacity-scheduler.xml');
  928. }
  929. this.saveSiteConfigs(configs);
  930. /**
  931. * First we put cluster configurations, which automatically creates /configurations
  932. * resources. Next we update host level overrides.
  933. */
  934. result.flag = this.doPUTClusterConfigurations();
  935. } else {
  936. var overridenConfigs = [];
  937. var groupHosts = [];
  938. configs.filterProperty('isOverridden', true).forEach(function (config) {
  939. overridenConfigs = overridenConfigs.concat(config.get('overrides'));
  940. });
  941. this.formatConfigValues(overridenConfigs);
  942. selectedConfigGroup.get('hosts').forEach(function(hostName){
  943. groupHosts.push({"host_name": hostName});
  944. });
  945. this.putConfigGroupChanges({
  946. ConfigGroup: {
  947. "id": selectedConfigGroup.get('id'),
  948. "cluster_name": App.get('clusterName'),
  949. "group_name": selectedConfigGroup.get('name'),
  950. "tag": selectedConfigGroup.get('service.id'),
  951. "description": selectedConfigGroup.get('description'),
  952. "hosts": groupHosts,
  953. "desired_configs": this.buildGroupDesiredConfigs(overridenConfigs)
  954. }
  955. });
  956. result.flag = this.get('isPutConfigGroupChangesSuccess');
  957. }
  958. if (!result.flag) {
  959. result.message = Em.I18n.t('services.service.config.failSaveConfig');
  960. } else {
  961. if (!result.flag) {
  962. result.message = Em.I18n.t('services.service.config.failSaveConfigHostOverrides');
  963. }
  964. }
  965. console.log("The result from applyCreatdConfToService is: " + result);
  966. return result;
  967. },
  968. /**
  969. * construct desired_configs for config groups from overriden properties
  970. * @param configs
  971. * @param timeTag
  972. * @return {Array}
  973. */
  974. buildGroupDesiredConfigs: function (configs, timeTag) {
  975. var sites = [];
  976. var time = timeTag || (new Date).getTime();
  977. configs.forEach(function (config) {
  978. var type = config.get('filename').replace('.xml', '');
  979. var site = sites.findProperty('type', type);
  980. if (site) {
  981. site.properties.push({
  982. name: config.get('name'),
  983. value: config.get('value')
  984. });
  985. } else {
  986. site = {
  987. type: type,
  988. tag: 'version' + time,
  989. properties: [{
  990. name: config.get('name'),
  991. value: config.get('value')
  992. }]
  993. };
  994. sites.push(site);
  995. }
  996. });
  997. sites.forEach(function(site){
  998. if(site.type === 'global') {
  999. site.properties = this.createGlobalSiteObj(site.tag, site.properties).properties;
  1000. } else {
  1001. site.properties = this.createSiteObj(site.type, site.tag, site.properties).properties;
  1002. }
  1003. }, this);
  1004. return sites;
  1005. },
  1006. /**
  1007. * persist properties of config groups to server
  1008. * @param data
  1009. */
  1010. putConfigGroupChanges: function (data) {
  1011. App.ajax.send({
  1012. name: 'config_groups.update_config_group',
  1013. sender: this,
  1014. data: {
  1015. id: data.ConfigGroup.id,
  1016. configGroup: data
  1017. },
  1018. success: "putConfigGroupChangesSuccess"
  1019. });
  1020. },
  1021. isPutConfigGroupChangesSuccess: false,
  1022. putConfigGroupChangesSuccess: function () {
  1023. this.set('isPutConfigGroupChangesSuccess', true);
  1024. },
  1025. /**
  1026. * save new or change exist configs in global configs
  1027. * @param configs
  1028. */
  1029. saveGlobalConfigs: function (configs) {
  1030. var globalConfigs = this.get('globalConfigs');
  1031. configs.filterProperty('id', 'puppet var').forEach(function (uiConfigProperty) {
  1032. uiConfigProperty.set('value', App.config.trimProperty(uiConfigProperty));
  1033. if (globalConfigs.someProperty('name', uiConfigProperty.name)) {
  1034. var modelGlobalConfig = globalConfigs.findProperty('name', uiConfigProperty.name);
  1035. modelGlobalConfig.value = uiConfigProperty.value;
  1036. } else {
  1037. globalConfigs.pushObject({
  1038. name: uiConfigProperty.name,
  1039. value: uiConfigProperty.value
  1040. });
  1041. }
  1042. }, this);
  1043. this.setHiveHostName(globalConfigs);
  1044. this.setOozieHostName(globalConfigs);
  1045. this.set('globalConfigs', globalConfigs);
  1046. },
  1047. /**
  1048. * set hive hostnames in global configs
  1049. * @param globals
  1050. */
  1051. setHiveHostName: function (globals) {
  1052. if (globals.someProperty('name', 'hive_database')) {
  1053. var hiveDb = globals.findProperty('name', 'hive_database');
  1054. if (hiveDb.value === 'New MySQL Database') {
  1055. var ambariHost = globals.findProperty('name', 'hive_ambari_host');
  1056. if (ambariHost) {
  1057. ambariHost.name = 'hive_hostname';
  1058. }
  1059. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1060. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1061. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1062. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1063. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1064. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1065. } else if (hiveDb.value === 'Existing MySQL Database') {
  1066. var existingMySqlHost = globals.findProperty('name', 'hive_existing_mysql_host');
  1067. if (existingMySqlHost) {
  1068. existingMySqlHost.name = 'hive_hostname';
  1069. }
  1070. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1071. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1072. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1073. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1074. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1075. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1076. } else if (hiveDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
  1077. var existingPostgreSqlHost = globals.findProperty('name', 'hive_existing_postgresql_host');
  1078. if (existingPostgreSqlHost) {
  1079. existingPostgreSqlHost.name = 'hive_hostname';
  1080. }
  1081. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1082. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1083. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1084. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1085. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1086. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1087. }
  1088. else { //existing oracle database
  1089. var existingOracleHost = globals.findProperty('name', 'hive_existing_oracle_host');
  1090. if (existingOracleHost) {
  1091. existingOracleHost.name = 'hive_hostname';
  1092. }
  1093. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1094. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1095. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1096. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1097. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1098. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1099. }
  1100. }
  1101. },
  1102. /**
  1103. * set oozie hostnames in global configs
  1104. * @param globals
  1105. */
  1106. setOozieHostName: function (globals) {
  1107. if (globals.someProperty('name', 'oozie_database')) {
  1108. var oozieDb = globals.findProperty('name', 'oozie_database');
  1109. if (oozieDb.value === 'New Derby Database') {
  1110. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1111. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1112. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1113. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1114. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1115. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1116. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1117. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1118. } else if (oozieDb.value === 'New MySQL Database') {
  1119. var ambariHost = globals.findProperty('name', 'oozie_ambari_host');
  1120. if (ambariHost) {
  1121. ambariHost.name = 'oozie_hostname';
  1122. }
  1123. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1124. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1125. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1126. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1127. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1128. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1129. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1130. } else if (oozieDb.value === 'Existing MySQL Database') {
  1131. var existingMySqlHost = globals.findProperty('name', 'oozie_existing_mysql_host');
  1132. if (existingMySqlHost) {
  1133. existingMySqlHost.name = 'oozie_hostname';
  1134. }
  1135. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1136. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1137. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1138. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1139. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1140. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1141. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1142. } else if (oozieDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
  1143. var existingPostgreSqlHost = globals.findProperty('name', 'oozie_existing_postgresql_host');
  1144. if (existingPostgreSqlHost) {
  1145. existingPostgreSqlHost.name = 'oozie_hostname';
  1146. }
  1147. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1148. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1149. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1150. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1151. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1152. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1153. }
  1154. else { //existing oracle database
  1155. var existingOracleHost = globals.findProperty('name', 'oozie_existing_oracle_host');
  1156. if (existingOracleHost) {
  1157. existingOracleHost.name = 'oozie_hostname';
  1158. }
  1159. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1160. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1161. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1162. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1163. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1164. }
  1165. }
  1166. },
  1167. /**
  1168. * save site configs
  1169. * @param configs
  1170. */
  1171. saveSiteConfigs: function (configs) {
  1172. //storedConfigs contains custom configs as well
  1173. var serviceConfigProperties = configs.filterProperty('id', 'site property');
  1174. this.formatConfigValues(serviceConfigProperties);
  1175. var storedConfigs = serviceConfigProperties.filterProperty('value');
  1176. var mappedConfigs = App.config.excludeUnsupportedConfigs(this.get('configMapping').all(), App.Service.find().mapProperty('serviceName'));
  1177. var allUiConfigs = this.loadUiSideConfigs(mappedConfigs);
  1178. this.set('uiConfigs', storedConfigs.concat(allUiConfigs));
  1179. },
  1180. formatConfigValues: function(serviceConfigProperties){
  1181. serviceConfigProperties.forEach(function (_config) {
  1182. if (typeof _config.get('value') === "boolean") _config.set('value', _config.value.toString());
  1183. _config.set('value', App.config.trimProperty(_config, true));
  1184. });
  1185. },
  1186. /**
  1187. * return configs from the UI side
  1188. * @param configMapping array with configs
  1189. * @return {Array}
  1190. */
  1191. loadUiSideConfigs: function (configMapping) {
  1192. var uiConfig = [];
  1193. var configs = configMapping.filterProperty('foreignKey', null);
  1194. this.addDynamicProperties(configs);
  1195. configs.forEach(function (_config) {
  1196. var valueWithOverrides = this.getGlobConfigValueWithOverrides(_config.templateName, _config.value);
  1197. if (valueWithOverrides !== null) {
  1198. uiConfig.pushObject({
  1199. "id": "site property",
  1200. "name": _config.name,
  1201. "value": valueWithOverrides.value,
  1202. "filename": _config.filename,
  1203. "overrides": valueWithOverrides.overrides
  1204. });
  1205. }
  1206. }, this);
  1207. return uiConfig;
  1208. },
  1209. addDynamicProperties: function (configs) {
  1210. var allConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
  1211. var templetonHiveProperty = allConfigs.someProperty('name', 'templeton.hive.properties');
  1212. if (!templetonHiveProperty && this.get('content.serviceName') === 'WEBHCAT') {
  1213. configs.pushObject({
  1214. "name": "templeton.hive.properties",
  1215. "templateName": ["hivemetastore_host"],
  1216. "foreignKey": null,
  1217. "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",
  1218. "filename": "webhcat-site.xml"
  1219. });
  1220. }
  1221. },
  1222. /**
  1223. * return global config value
  1224. * @param templateName
  1225. * @param expression
  1226. * @return {Object}
  1227. * example: <code>{
  1228. * value: '...',
  1229. * overrides: {
  1230. * 'value1': [h1, h2],
  1231. * 'value2': [h3]
  1232. * }
  1233. * }</code>
  1234. */
  1235. getGlobConfigValueWithOverrides: function (templateName, expression) {
  1236. var express = expression.match(/<(.*?)>/g);
  1237. var value = expression;
  1238. var overrideHostToValue = {};
  1239. if (express != null) {
  1240. express.forEach(function (_express) {
  1241. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  1242. var globalObj = this.get('globalConfigs').findProperty('name', templateName[index]);
  1243. if (globalObj) {
  1244. var globOverride = globalObj.overrides;
  1245. if (globOverride != null) {
  1246. for (var ov in globOverride) {
  1247. globOverride[ov].forEach(function (host) {
  1248. var replacedVal = (host in overrideHostToValue) ? overrideHostToValue[host] : expression;
  1249. overrideHostToValue[host] = replacedVal.replace(_express, ov);
  1250. }, this);
  1251. }
  1252. }
  1253. value = expression.replace(_express, globalObj.value);
  1254. } else {
  1255. value = null;
  1256. }
  1257. }, this);
  1258. }
  1259. return this.getValueWithOverrides(value, overrideHostToValue)
  1260. },
  1261. getValueWithOverrides: function(value, overrideHostToValue) {
  1262. var valueWithOverrides = {
  1263. value: value,
  1264. overrides: {}
  1265. };
  1266. if (!jQuery.isEmptyObject(overrideHostToValue)) {
  1267. for (var host in overrideHostToValue) {
  1268. var hostVal = overrideHostToValue[host];
  1269. if (!(hostVal in valueWithOverrides.overrides)) {
  1270. valueWithOverrides.overrides[hostVal] = [];
  1271. }
  1272. valueWithOverrides.overrides[hostVal].push(host);
  1273. }
  1274. }
  1275. return valueWithOverrides;
  1276. },
  1277. /**
  1278. * Saves cluster level configurations for all necessary sites.
  1279. * PUT calls are made to /api/v1/clusters/clusterName for each site.
  1280. * @return {Boolean}
  1281. * @method doPUTClusterConfigurations
  1282. */
  1283. doPUTClusterConfigurations: function () {
  1284. var result = true;
  1285. var serviceConfigTags = this.get('serviceConfigTags');
  1286. this.setNewTagNames(serviceConfigTags);
  1287. var siteNameToServerDataMap = {};
  1288. serviceConfigTags.forEach(function (_serviceTags) {
  1289. var configs = this.createConfigObject(_serviceTags.siteName, _serviceTags.newTagName);
  1290. if (configs) {
  1291. result = result && this.doPUTClusterConfiguration(siteNameToServerDataMap, _serviceTags.siteName, configs);
  1292. }
  1293. }, this);
  1294. this.set("savedSiteNameToServerServiceConfigDataMap", siteNameToServerDataMap);
  1295. return result;
  1296. },
  1297. /**
  1298. * create different config object depending on siteName
  1299. * @param {String} siteName
  1300. * @param {String} tagName
  1301. * @returns {Object|undefined}
  1302. * @method createConfigObject
  1303. */
  1304. createConfigObject: function(siteName, tagName) {
  1305. console.log("TRACE: Inside " + siteName);
  1306. switch(siteName) {
  1307. case 'global':
  1308. return this.createGlobalSiteObj(tagName, this.get('globalConfigs'));
  1309. case 'core-site':
  1310. if(this.get('content.serviceName') === 'HDFS' || this.get('content.serviceName') === 'GLUSTERFS') {
  1311. return this.createCoreSiteObj(tagName);
  1312. }
  1313. return;
  1314. default:
  1315. var filename = (App.config.get('filenameExceptions').contains(siteName)) ? siteName : siteName + '.xml';
  1316. if (filename === 'mapred-queue-acls.xml' && !App.supports.capacitySchedulerUi) {
  1317. return;
  1318. }
  1319. return this.createSiteObj(siteName, tagName, this.get('uiConfigs').filterProperty('filename', filename));
  1320. }
  1321. },
  1322. /**
  1323. * load existen properties and compare them with current if there are
  1324. * differences - trigger doPUTClusterConfigurationSite to save new properties
  1325. * @param {Object} siteNameToServerDataMap
  1326. * @param {String} siteName
  1327. * @param {Object} configs
  1328. * @returns {Boolean} true if config successfully saved or there
  1329. * is no need to save them
  1330. * @method doPUTClusterConfiguration
  1331. */
  1332. doPUTClusterConfiguration: function(siteNameToServerDataMap, siteName, configs) {
  1333. var loadedProperties;
  1334. siteNameToServerDataMap[siteName] = configs;
  1335. loadedProperties = App.router.get('configurationController').getConfigsByTags([{siteName: siteName, tagName: this.loadedClusterSiteToTagMap[siteName]}]);
  1336. if (loadedProperties && loadedProperties[0]) {
  1337. loadedProperties = loadedProperties[0].properties;
  1338. }
  1339. if (!loadedProperties) {
  1340. loadedProperties = {};
  1341. }
  1342. if (this.isConfigChanged(loadedProperties, configs.properties)) {
  1343. return this.doPUTClusterConfigurationSite(configs);
  1344. }
  1345. return true;
  1346. },
  1347. /**
  1348. * Compares the loaded config values with the saving config values.
  1349. * @param {Object} loadedConfig -
  1350. * loadedConfig: {
  1351. * configName1: "configValue1",
  1352. * configName2: "configValue2"
  1353. * }
  1354. * @param {Object} savingConfig
  1355. * savingConfig: {
  1356. * configName1: "configValue1",
  1357. * configName2: "configValue2"
  1358. * }
  1359. * @returns {boolean}
  1360. * @method isConfigChanged
  1361. */
  1362. isConfigChanged: function (loadedConfig, savingConfig) {
  1363. var changed = false;
  1364. if (loadedConfig != null && savingConfig != null) {
  1365. var seenLoadKeys = [];
  1366. for (var loadKey in loadedConfig) {
  1367. if (!loadedConfig.hasOwnProperty(loadKey)) continue;
  1368. seenLoadKeys.push(loadKey);
  1369. var loadValue = loadedConfig[loadKey];
  1370. var saveValue = savingConfig[loadKey];
  1371. if ("boolean" == typeof(saveValue)) {
  1372. saveValue = saveValue.toString();
  1373. }
  1374. if (saveValue == null) {
  1375. saveValue = "null";
  1376. }
  1377. if (loadValue !== saveValue) {
  1378. changed = true;
  1379. break;
  1380. }
  1381. }
  1382. for (var saveKey in savingConfig) {
  1383. if (seenLoadKeys.indexOf(saveKey) < 0) {
  1384. changed = true;
  1385. break;
  1386. }
  1387. }
  1388. }
  1389. return changed;
  1390. },
  1391. /**
  1392. * Saves configuration of a particular site. The provided data
  1393. * contains the site name and tag to be used.
  1394. * @param {Object} data
  1395. * @return {bool}
  1396. * @method doPUTClusterConfigurationSite
  1397. */
  1398. doPUTClusterConfigurationSite: function (data) {
  1399. App.ajax.send({
  1400. name: 'config.cluster_configuration.put',
  1401. sender: this,
  1402. data: {
  1403. data: JSON.stringify({
  1404. Clusters: {
  1405. desired_config: data
  1406. }
  1407. }),
  1408. cluster: App.router.getClusterName()
  1409. },
  1410. success: 'doPUTClusterConfigurationSiteSuccessCallback',
  1411. error: 'doPUTClusterConfigurationSiteErrorCallback'
  1412. });
  1413. return this.get('doPUTClusterConfigurationSiteResult');
  1414. },
  1415. /**
  1416. * @type {bool}
  1417. */
  1418. doPUTClusterConfigurationSiteResult: null,
  1419. /**
  1420. * set doPUTClusterConfigurationSiteResult to true and write info to log
  1421. * @param {Object} data
  1422. * @method doPUTClusterConfigurationSiteSuccessCallback
  1423. */
  1424. doPUTClusterConfigurationSiteSuccessCallback: function(data) {
  1425. console.log("applyClusterConfigurationToSite(): In success for data:", data);
  1426. this.set('doPUTClusterConfigurationSiteResult', true);
  1427. },
  1428. /**
  1429. * set doPUTClusterConfigurationSiteResult to false and write info to log
  1430. * @param {Object} request
  1431. * @param {Object} ajaxOptions
  1432. * @param {String} error
  1433. * @method doPUTClusterConfigurationSiteSuccessCallback
  1434. */
  1435. doPUTClusterConfigurationSiteErrorCallback: function(request, ajaxOptions, error) {
  1436. console.log('applyClusterConfigurationToSite(): ERROR:', request.responseText, ", error=", error);
  1437. this.set('doPUTClusterConfigurationSiteResult', false);
  1438. },
  1439. /**
  1440. * add newTagName property to each config in serviceConfigs
  1441. * @param serviceConfigs
  1442. */
  1443. setNewTagNames: function (serviceConfigs) {
  1444. var time = (new Date).getTime();
  1445. serviceConfigs.forEach(function (_serviceConfigs) {
  1446. _serviceConfigs.newTagName = 'version' + time;
  1447. }, this);
  1448. },
  1449. /**
  1450. * create global site object
  1451. * @param {String} tagName
  1452. * @param {Array} globalConfigs array of config objects
  1453. * @return {{"type": String, "tag": String, "properties": Object}}
  1454. * @method createGlobalSiteObj
  1455. */
  1456. createGlobalSiteObj: function (tagName, globalConfigs) {
  1457. var heapsizeException = ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize', 'jobhistory_heapsize'];
  1458. var globalSiteProperties = {};
  1459. globalConfigs.forEach(function (_globalSiteObj) {
  1460. // do not pass any globalConfigs whose name ends with _host or _hosts
  1461. if (_globalSiteObj.isRequiredByAgent !== false) {
  1462. // append "m" to JVM memory options except for hadoop_heapsize
  1463. if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
  1464. _globalSiteObj.value += "m";
  1465. }
  1466. globalSiteProperties[_globalSiteObj.name] = App.config.escapeXMLCharacters(_globalSiteObj.value);
  1467. //this.recordHostOverride(_globalSiteObj, 'global', tagName, this);
  1468. //console.log("TRACE: name of the global property is: " + _globalSiteObj.name);
  1469. //console.log("TRACE: value of the global property is: " + _globalSiteObj.value);
  1470. }
  1471. }, this);
  1472. return {"type": "global", "tag": tagName, "properties": globalSiteProperties};
  1473. },
  1474. /**
  1475. * create core site object
  1476. * @param tagName
  1477. * @return {{"type": String, "tag": String, "properties": Object}}
  1478. * @method createCoreSiteObj
  1479. */
  1480. createCoreSiteObj: function (tagName) {
  1481. var coreSiteObj = this.get('uiConfigs').filterProperty('filename', 'core-site.xml');
  1482. var coreSiteProperties = {};
  1483. coreSiteObj.forEach(function (_coreSiteObj) {
  1484. coreSiteProperties[_coreSiteObj.name] = App.config.escapeXMLCharacters(_coreSiteObj.value);
  1485. //this.recordHostOverride(_coreSiteObj, 'core-site', tagName, this);
  1486. }, this);
  1487. return {"type": "core-site", "tag": tagName, "properties": coreSiteProperties};
  1488. },
  1489. /**
  1490. * create site object
  1491. * @param siteName
  1492. * @param tagName
  1493. * @param siteObj
  1494. * @return {Object}
  1495. */
  1496. createSiteObj: function (siteName, tagName, siteObj) {
  1497. var siteProperties = {};
  1498. siteObj.forEach(function (_siteObj) {
  1499. switch(siteName) {
  1500. case 'falcon-startup.properties':
  1501. case 'falcon-runtime.properties':
  1502. siteProperties[_siteObj.name] = _siteObj.value;
  1503. break;
  1504. default:
  1505. siteProperties[_siteObj.name] = this.setServerConfigValue(_siteObj.name, _siteObj.value);
  1506. }
  1507. }, this);
  1508. return {"type": siteName, "tag": tagName, "properties": siteProperties};
  1509. },
  1510. /**
  1511. * This method will be moved to config's decorators class.
  1512. *
  1513. * For now, provide handling for special properties that need
  1514. * be specified in special format required for server.
  1515. *
  1516. * @param configName {String} - name of config property
  1517. * @param value {Mixed} - value of config property
  1518. *
  1519. * @return {String} - formated value
  1520. */
  1521. setServerConfigValue: function (configName, value) {
  1522. switch (configName) {
  1523. case 'storm.zookeeper.servers':
  1524. return JSON.stringify(value).replace(/"/g, "'");
  1525. break;
  1526. case 'content':
  1527. return value;
  1528. break;
  1529. default:
  1530. return App.config.escapeXMLCharacters(value);
  1531. }
  1532. },
  1533. /**
  1534. * Array of Objects
  1535. * {
  1536. * hostProperty - hostName property name for current component
  1537. * componentName - master componentName
  1538. * serviceName - serviceName of component
  1539. * serviceUseThis - services that use hostname property of component(componentName)
  1540. * m(multiple) - true if can be more than one components installed on cluster
  1541. * }
  1542. */
  1543. hostComponentsmapping: [
  1544. {
  1545. hostProperty: 'namenode_host',
  1546. componentName: 'NAMENODE',
  1547. serviceName: 'HDFS',
  1548. serviceUseThis: [],
  1549. m: true
  1550. },
  1551. {
  1552. hostProperty: 'snamenode_host',
  1553. componentName: 'SECONDARY_NAMENODE',
  1554. serviceName: 'HDFS',
  1555. serviceUseThis: []
  1556. },
  1557. {
  1558. hostProperty: 'jobtracker_host',
  1559. componentName: 'JOBTRACKER',
  1560. serviceName: 'MAPREDUCE',
  1561. serviceUseThis: []
  1562. },
  1563. {
  1564. hostProperty: 'jobtracker_host',
  1565. componentName: 'JOBTRACKER',
  1566. serviceName: 'MAPREDUCE2',
  1567. serviceUseThis: []
  1568. },
  1569. {
  1570. hostProperty: 'hs_host',
  1571. componentName: 'HISTORYSERVER',
  1572. serviceName: 'MAPREDUCE2',
  1573. serviceUseThis: ['YARN']
  1574. },
  1575. {
  1576. hostProperty: 'ats_host',
  1577. componentName: 'APP_TIMELINE_SERVER',
  1578. serviceName: 'YARN',
  1579. serviceUseThis: []
  1580. },
  1581. {
  1582. hostProperty: 'rm_host',
  1583. componentName: 'RESOURCEMANAGER',
  1584. serviceName: 'YARN',
  1585. serviceUseThis: []
  1586. },
  1587. {
  1588. hostProperty: 'hivemetastore_host',
  1589. componentName: 'HIVE_SERVER',
  1590. serviceName: 'HIVE',
  1591. serviceUseThis: ['WEBHCAT']
  1592. },
  1593. {
  1594. hostProperty: 'oozieserver_host',
  1595. componentName: 'OOZIE_SERVER',
  1596. serviceName: 'OOZIE',
  1597. serviceUseThis: []
  1598. },
  1599. {
  1600. hostProperty: 'hbasemaster_host',
  1601. componentName: 'HBASE_MASTER',
  1602. serviceName: 'HBASE',
  1603. serviceUseThis: [],
  1604. m: true
  1605. },
  1606. {
  1607. hostProperty: 'hueserver_host',
  1608. componentName: 'HUE_SERVER',
  1609. serviceName: 'HUE',
  1610. serviceUseThis: []
  1611. },
  1612. {
  1613. hostProperty: 'webhcatserver_host',
  1614. componentName: 'WEBHCAT_SERVER',
  1615. serviceName: 'WEBHCAT',
  1616. serviceUseThis: [],
  1617. m: true
  1618. },
  1619. {
  1620. hostProperty: 'zookeeperserver_hosts',
  1621. componentName: 'ZOOKEEPER_SERVER',
  1622. serviceName: 'ZOOKEEPER',
  1623. serviceUseThis: ['HBASE', 'WEBHCAT'],
  1624. m: true
  1625. },
  1626. {
  1627. hostProperty: 'stormuiserver_host',
  1628. componentName: 'STORM_UI_SERVER',
  1629. serviceName: 'STORM',
  1630. serviceUseThis: []
  1631. },
  1632. {
  1633. hostProperty: 'drpcserver_host',
  1634. componentName: 'DRPC_SERVER',
  1635. serviceName: 'STORM',
  1636. serviceUseThis: []
  1637. },
  1638. {
  1639. hostProperty: 'storm_rest_api_host',
  1640. componentName: 'STORM_REST_API',
  1641. serviceName: 'STORM',
  1642. serviceUseThis: []
  1643. },
  1644. {
  1645. hostProperty: 'supervisor_hosts',
  1646. componentName: 'SUPERVISOR',
  1647. serviceName: 'STORM',
  1648. serviceUseThis: [],
  1649. m: true
  1650. }
  1651. ],
  1652. /**
  1653. * Adds host name of master component to global config;
  1654. * @method addHostNamesToGlobalConfig
  1655. */
  1656. addHostNamesToGlobalConfig: function () {
  1657. var serviceName = this.get('content.serviceName');
  1658. var globalConfigs = this.get('globalConfigs');
  1659. //namenode_host is required to derive "fs.default.name" a property of core-site
  1660. try {
  1661. this.setHostForService('HDFS', 'NAMENODE', 'namenode_host', true);
  1662. } catch (err) {
  1663. console.log("No NameNode Host available. This is expected if you're using GLUSTERFS rather than HDFS.");
  1664. }
  1665. var hostProperties = this.get('hostComponentsmapping').filter(function(h) {
  1666. return h.serviceUseThis.contains(serviceName) || h.serviceName == serviceName;
  1667. });
  1668. hostProperties.forEach(function(h) {
  1669. this.setHostForService(h.serviceName, h.componentName, h.hostProperty, h.m);
  1670. }, this);
  1671. if (serviceName === 'HIVE') {
  1672. var hiveDb = globalConfigs.findProperty('name', 'hive_database').value;
  1673. if (['Existing MySQL Database', 'Existing Oracle Database'].contains(hiveDb)) {
  1674. globalConfigs.findProperty('name', 'hive_hostname').isVisible = true;
  1675. }
  1676. }
  1677. if (serviceName === 'OOZIE') {
  1678. var oozieDb = globalConfigs.findProperty('name', 'oozie_database').value;
  1679. if (['Existing MySQL Database', 'Existing Oracle Database'].contains(oozieDb)) {
  1680. globalConfigs.findProperty('name', 'oozie_hostname').isVisible = true;
  1681. }
  1682. }
  1683. },
  1684. /**
  1685. * set host name(s) property for component
  1686. * @param {String} serviceName - service name of component
  1687. * @param {String} componentName - component name whic host we want to know
  1688. * @param {String} hostProperty - name of host property for current component
  1689. * @param {Boolean} multiple - true if can be more than one component
  1690. * @method setHostForService
  1691. */
  1692. setHostForService: function(serviceName, componentName, hostProperty, multiple) {
  1693. var globalConfigs = this.get('globalConfigs');
  1694. var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).configs;
  1695. var hostConfig = serviceConfigs.findProperty('name', hostProperty);
  1696. if (hostConfig) {
  1697. hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);
  1698. globalConfigs.push(hostConfig);
  1699. }
  1700. },
  1701. /**
  1702. * get hostName of component
  1703. * @param {String} componentName
  1704. * @param {Boolean} multiple - true if can be more than one component installed on cluster
  1705. * @return {String|Array|Boolean} hostName|hostNames|false if missing component
  1706. * @method getMasterComponentHostValue
  1707. */
  1708. getMasterComponentHostValue: function(componentName, multiple) {
  1709. var components = this.get('content.hostComponents').filterProperty('componentName', componentName);
  1710. if (components.length > 0) {
  1711. return multiple ? components.mapProperty('host.hostName') : components[0].get('host.hostName');
  1712. }
  1713. return false;
  1714. },
  1715. /**
  1716. * Provides service component name and display-name information for
  1717. * the current selected service.
  1718. * @return {Em.Array} validComponents - array of valid components
  1719. * @method getCurrentServiceComponents
  1720. */
  1721. getCurrentServiceComponents: function () {
  1722. var components = this.get('content.hostComponents');
  1723. var validComponents = Ember.A([]);
  1724. var seenComponents = {};
  1725. components.forEach(function (component) {
  1726. var cn = component.get('componentName');
  1727. var cdn = component.get('displayName');
  1728. if (!seenComponents[cn]) {
  1729. validComponents.push(Ember.Object.create({
  1730. componentName: cn,
  1731. displayName: cdn,
  1732. selected: false
  1733. }));
  1734. seenComponents[cn] = cn;
  1735. }
  1736. });
  1737. return validComponents;
  1738. }.property('content'),
  1739. /**
  1740. * trigger loadStep
  1741. * @method loadStep
  1742. */
  1743. doCancel: function () {
  1744. this.loadStep();
  1745. },
  1746. /**
  1747. * trigger restartAllServiceHostComponents(batchUtils) if confirmed in popup
  1748. * @method restartAllStaleConfigComponents
  1749. * @return App.showConfirmationFeedBackPopup
  1750. */
  1751. restartAllStaleConfigComponents: function() {
  1752. var self = this;
  1753. var serviceDisplayName = this.get('content.displayName');
  1754. var bodyMessage = Em.Object.create({
  1755. confirmMsg: Em.I18n.t('services.service.restartAll.confirmMsg').format(serviceDisplayName),
  1756. confirmButton: Em.I18n.t('services.service.restartAll.confirmButton'),
  1757. additionalWarningMsg: this.get('content.passiveState') === 'OFF' ? Em.I18n.t('services.service.restartAll.warningMsg.turnOnMM').format(serviceDisplayName): null
  1758. });
  1759. return App.showConfirmationFeedBackPopup(function(query) {
  1760. var selectedService = self.get('content.id');
  1761. batchUtils.restartAllServiceHostComponents(selectedService, true, query);
  1762. }, bodyMessage);
  1763. },
  1764. /**
  1765. * trigger launchHostComponentRollingRestart(batchUtils)
  1766. * @method rollingRestartStaleConfigSlaveComponents
  1767. */
  1768. rollingRestartStaleConfigSlaveComponents: function(componentName) {
  1769. batchUtils.launchHostComponentRollingRestart(componentName.context, this.get('content.displayName'), this.get('content.passiveState') === "ON", true);
  1770. },
  1771. /**
  1772. * trigger showItemsShouldBeRestarted popup with hosts that requires resetart
  1773. * @method showHostsShouldBeRestarted
  1774. */
  1775. showHostsShouldBeRestarted: function() {
  1776. var hosts = [];
  1777. for(var hostName in this.get('content.restartRequiredHostsAndComponents')) {
  1778. hosts.push(hostName);
  1779. }
  1780. var hostsText = hosts.length == 1 ? Em.I18n.t('common.host') : Em.I18n.t('common.hosts');
  1781. hosts = hosts.join(', ');
  1782. this.showItemsShouldBeRestarted(hosts, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(hostsText));
  1783. },
  1784. /**
  1785. * trigger showItemsShouldBeRestarted popup with components that requires resetart
  1786. * @method showComponentsShouldBeRestarted
  1787. */
  1788. showComponentsShouldBeRestarted: function() {
  1789. var rhc = this.get('content.restartRequiredHostsAndComponents');
  1790. var hostsComponets = [];
  1791. var componentsObject = {};
  1792. for(var hostName in rhc) {
  1793. rhc[hostName].forEach(function(hostComponent) {
  1794. hostsComponets.push(hostComponent);
  1795. if(componentsObject[hostComponent] != undefined) {
  1796. componentsObject[hostComponent]++;
  1797. } else {
  1798. componentsObject[hostComponent] = 1;
  1799. }
  1800. })
  1801. }
  1802. var componentsList = [];
  1803. for( var obj in componentsObject) {
  1804. var componentDisplayName = (componentsObject[obj] > 1) ? obj + 's' : obj;
  1805. componentsList.push(componentsObject[obj] + ' ' + componentDisplayName);
  1806. }
  1807. var componentsText = componentsList.length == 1 ? Em.I18n.t('common.component') : Em.I18n.t('common.components');
  1808. hostsComponets = componentsList.join(', ');
  1809. this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(componentsText));
  1810. },
  1811. showItemsShouldBeRestarted: function(content, header) {
  1812. App.ModalPopup.show({
  1813. content: content,
  1814. header: header,
  1815. bodyClass: Em.View.extend({
  1816. templateName: require('templates/common/selectable_popup'),
  1817. textareaVisible: false,
  1818. textTrigger: function() {
  1819. this.set('textareaVisible', !this.get('textareaVisible'));
  1820. },
  1821. putContentToTextarea: function() {
  1822. var content = this.get('parentView.content');
  1823. if (this.get('textareaVisible')) {
  1824. var wrapper = $(".task-detail-log-maintext");
  1825. $('.task-detail-log-clipboard').html(content).width(wrapper.width()).height(wrapper.height());
  1826. Em.run.next(function() {
  1827. $('.task-detail-log-clipboard').select();
  1828. });
  1829. }
  1830. }.observes('textareaVisible')
  1831. }),
  1832. secondary: null
  1833. });
  1834. },
  1835. /**
  1836. * add new overridden property to config property object
  1837. * @param {object} serviceConfigProperty - config property object
  1838. * @method addOverrideProperty
  1839. */
  1840. addOverrideProperty: function(serviceConfigProperty) {
  1841. var overrides = serviceConfigProperty.get('overrides');
  1842. if (!overrides) {
  1843. overrides = [];
  1844. serviceConfigProperty.set('overrides', overrides);
  1845. }
  1846. // create new override with new value
  1847. var newSCP = App.ServiceConfigProperty.create(serviceConfigProperty);
  1848. newSCP.set('value', '');
  1849. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  1850. newSCP.set('parentSCP', serviceConfigProperty);
  1851. newSCP.set('isEditable', true);
  1852. console.debug("createOverrideProperty(): Added:", newSCP, " to main-property:", serviceConfigProperty);
  1853. overrides.pushObject(newSCP);
  1854. },
  1855. /**
  1856. * trigger manageConfigurationGroups
  1857. * @method manageConfigurationGroup
  1858. */
  1859. manageConfigurationGroup: function () {
  1860. this.manageConfigurationGroups();
  1861. },
  1862. manageConfigurationGroups: function (controller) {
  1863. var serviceData = (controller && controller.get('selectedService')) || this.get('content');
  1864. var serviceName = serviceData.get('serviceName');
  1865. var displayName = serviceData.get('displayName');
  1866. App.router.get('manageConfigGroupsController').set('isInstaller', !!controller);
  1867. return App.ModalPopup.show({
  1868. header: Em.I18n.t('services.service.config_groups_popup.header').format(displayName),
  1869. bodyClass: App.MainServiceManageConfigGroupView.extend({
  1870. serviceName: serviceName,
  1871. displayName: displayName,
  1872. controllerBinding: 'App.router.manageConfigGroupsController'
  1873. }),
  1874. classNames: ['sixty-percent-width-modal', 'manage-configuration-group-popup'],
  1875. primary: Em.I18n.t('common.save'),
  1876. onPrimary: function() {
  1877. var modifiedConfigGroups = this.get('subViewController.hostsModifiedConfigGroups');
  1878. // Save modified config-groups
  1879. if (!!controller) {
  1880. controller.set('selectedService.configGroups', App.router.get('manageConfigGroupsController.configGroups'));
  1881. controller.selectedServiceObserver();
  1882. if (controller.get('name') == "wizardStep7Controller") {
  1883. if (controller.get('selectedService.selected') === false && modifiedConfigGroups.toDelete.length > 0) {
  1884. controller.setGroupsToDelete(modifiedConfigGroups.toDelete);
  1885. }
  1886. App.config.persistWizardStep7ConfigGroups();
  1887. this.updateConfigGroupOnServicePage();
  1888. }
  1889. this.hide();
  1890. return;
  1891. }
  1892. console.log("manageConfigurationGroups(): Saving modified config-groups: ", modifiedConfigGroups);
  1893. var self = this;
  1894. var errors = [];
  1895. var deleteQueriesCounter = modifiedConfigGroups.toClearHosts.length + modifiedConfigGroups.toDelete.length;
  1896. var createQueriesCounter = modifiedConfigGroups.toSetHosts.length + modifiedConfigGroups.toCreate.length;
  1897. var deleteQueriesRun = false;
  1898. var createQueriesRun = false;
  1899. var runNextQuery = function () {
  1900. if (!deleteQueriesRun && deleteQueriesCounter > 0) {
  1901. deleteQueriesRun = true;
  1902. modifiedConfigGroups.toClearHosts.forEach(function (cg) {
  1903. App.config.clearConfigurationGroupHosts(cg, finishFunction, finishFunction);
  1904. }, this);
  1905. modifiedConfigGroups.toDelete.forEach(function (cg) {
  1906. App.config.deleteConfigGroup(cg, finishFunction, finishFunction);
  1907. }, this);
  1908. } else if (!createQueriesRun && deleteQueriesCounter < 1) {
  1909. createQueriesRun = true;
  1910. modifiedConfigGroups.toSetHosts.forEach(function (cg) {
  1911. App.config.updateConfigurationGroup(cg, finishFunction, finishFunction);
  1912. }, this);
  1913. modifiedConfigGroups.toCreate.forEach(function (cg) {
  1914. App.config.postNewConfigurationGroup(cg, finishFunction);
  1915. }, this);
  1916. }
  1917. };
  1918. var finishFunction = function (xhr, text, errorThrown) {
  1919. if (xhr && errorThrown) {
  1920. var error = xhr.status + "(" + errorThrown + ") ";
  1921. try {
  1922. var json = $.parseJSON(xhr.responseText);
  1923. error += json.message;
  1924. } catch (err) {
  1925. }
  1926. console.error('Error updating Config Group:', error);
  1927. errors.push(error);
  1928. }
  1929. if (createQueriesRun) {
  1930. createQueriesCounter--;
  1931. } else {
  1932. deleteQueriesCounter--;
  1933. }
  1934. if (deleteQueriesCounter + createQueriesCounter < 1) {
  1935. if (errors.length > 0) {
  1936. console.log(errors);
  1937. self.get('subViewController').set('errorMessage', errors.join(". "));
  1938. } else {
  1939. self.updateConfigGroupOnServicePage();
  1940. self.hide();
  1941. }
  1942. } else {
  1943. runNextQuery();
  1944. }
  1945. };
  1946. runNextQuery();
  1947. },
  1948. onSecondary: function () {
  1949. this.hide();
  1950. },
  1951. onClose: function () {
  1952. this.hide();
  1953. },
  1954. subViewController: function () {
  1955. return App.router.get('manageConfigGroupsController');
  1956. }.property('App.router.manageConfigGroupsController'),
  1957. updateConfigGroupOnServicePage: function () {
  1958. var subViewController = this.get('subViewController');
  1959. var selectedConfigGroup = subViewController.get('selectedConfigGroup');
  1960. var managedConfigGroups = subViewController.get('configGroups');
  1961. if (!controller) {
  1962. controller = App.router.get('mainServiceInfoConfigsController');
  1963. controller.set('configGroups', managedConfigGroups);
  1964. } else {
  1965. controller.set('selectedService.configGroups', managedConfigGroups);
  1966. }
  1967. //check whether selectedConfigGroup was selected
  1968. if (selectedConfigGroup && controller.get('configGroups').someProperty('name', selectedConfigGroup.get('name'))) {
  1969. controller.set('selectedConfigGroup', selectedConfigGroup);
  1970. } else {
  1971. controller.set('selectedConfigGroup', managedConfigGroups.findProperty('isDefault', true));
  1972. }
  1973. },
  1974. updateButtons: function(){
  1975. var modified = this.get('subViewController.isHostsModified');
  1976. this.set('disablePrimary', !modified);
  1977. }.observes('subViewController.isHostsModified'),
  1978. secondary : Em.I18n.t('common.cancel'),
  1979. didInsertElement: function () {}
  1980. });
  1981. },
  1982. /**
  1983. * If user chabges cfg group if some configs was changed popup with propose to save changes must be shown
  1984. * @param {object} event - triggered event for selecting another config-group
  1985. * @method selectConfigGroup
  1986. */
  1987. selectConfigGroup: function (event) {
  1988. if (!this.get('isInit')) {
  1989. if (this.hasUnsavedChanges()) {
  1990. this.showSavePopup(null, event);
  1991. return;
  1992. }
  1993. }
  1994. this.set('selectedConfigGroup', event.context);
  1995. },
  1996. /**
  1997. * Are some unsaved changes available
  1998. * @returns {boolean}
  1999. */
  2000. hasUnsavedChanges: function() {
  2001. return this.get('hash') != this.getHash();
  2002. },
  2003. /**
  2004. * If some configs are changed and user navigates away or select another config-group, show this popup with propose to save changes
  2005. * @param {String} path
  2006. * @param {object} event - triggered event for selecting another config-group
  2007. * @method showSavePopup
  2008. */
  2009. showSavePopup: function (path, event) {
  2010. var self = this;
  2011. return App.ModalPopup.show({
  2012. header: Em.I18n.t('common.warning'),
  2013. body: Em.I18n.t('services.service.config.exitPopup.body'),
  2014. footerClass: Ember.View.extend({
  2015. templateName: require('templates/main/service/info/save_popup_footer'),
  2016. isSaveDisabled: function() {
  2017. return self.get('isSubmitDisabled');
  2018. }.property()
  2019. }),
  2020. primary: Em.I18n.t('common.save'),
  2021. secondary: Em.I18n.t('common.cancel'),
  2022. onSave: function () {
  2023. self.restartServicePopup();
  2024. this.hide();
  2025. },
  2026. onDiscard: function () {
  2027. if (path) {
  2028. self.set('forceTransition', true);
  2029. App.router.route(path);
  2030. } else if (event) {
  2031. // Prevent multiple popups
  2032. self.set('hash', self.getHash());
  2033. self.selectConfigGroup(event);
  2034. }
  2035. this.hide();
  2036. },
  2037. onCancel: function () {
  2038. this.hide();
  2039. }
  2040. });
  2041. }
  2042. });