config_initializer.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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('utils/configs/config_initializer_class');
  20. /**
  21. * Regexp for host with port ('hostName:1234')
  22. *
  23. * @type {string}
  24. */
  25. var hostWithPort = "([\\w|\\.]*)(?=:)";
  26. /**
  27. * Regexp for host with port and protocol ('://hostName:1234')
  28. *
  29. * @type {string}
  30. */
  31. var hostWithPrefix = ":\/\/" + hostWithPort;
  32. /**
  33. * Regexp used to determine if mount point is windows-like
  34. *
  35. * @type {RegExp}
  36. */
  37. var winRegex = /^([a-z]):\\?$/;
  38. /**
  39. * Settings for <code>host_with_component</code>-initializer
  40. * Used for configs with value equal to hostName that has <code>component</code>
  41. * Value may be modified with if <code>withModifier</code> is true (it is by default)
  42. * <code>hostWithPort</code>-regexp will be used in this case
  43. *
  44. * @see _initAsHostWithComponent
  45. * @param {string} component
  46. * @param {boolean} [withModifier=true]
  47. * @return {object}
  48. */
  49. function getSimpleComponentConfig(component, withModifier) {
  50. if (arguments.length === 1) {
  51. withModifier = true;
  52. }
  53. var config = {
  54. type: 'host_with_component',
  55. component: component
  56. };
  57. if (withModifier) {
  58. config.modifier = {
  59. type: 'regexp',
  60. regex: hostWithPort
  61. }
  62. }
  63. return config;
  64. }
  65. /**
  66. * Zookeeper-based configs don't have any customization settings
  67. *
  68. * @see _initAsZookeeperServersList
  69. * @returns {{type: string}}
  70. */
  71. function getZKBasedConfig() {
  72. return {
  73. type: 'zookeeper_based'
  74. };
  75. }
  76. /**
  77. * Almost the same to <code>getSimpleComponentConfig</code>, but with possibility to modify <code>replaceWith</code>-value
  78. * <code>prefix</code> is added before it
  79. * <code>suffix</code> is added after it
  80. * <code>hostWithPrefix</code>-regexp is used
  81. *
  82. * @see _initAsHostWithComponent
  83. * @param {string} component
  84. * @param {string} [prefix]
  85. * @param {string} [suffix]
  86. * @returns {object}
  87. */
  88. function getComponentConfigWithAffixes (component, prefix, suffix) {
  89. prefix = prefix || '';
  90. suffix = suffix || '';
  91. return {
  92. type: 'host_with_component',
  93. component: component,
  94. modifier: {
  95. type: 'regexp',
  96. regex: hostWithPrefix,
  97. prefix: prefix,
  98. suffix: suffix
  99. }
  100. };
  101. }
  102. /**
  103. * Settings for <code>hosts_with_components</code>-initializer
  104. * Used for configs with value equal to the hosts list
  105. * May set value as array (if <code>asArray</code> is true) or as comma-sepratated string (if <code>asArray</code> is false)
  106. *
  107. * @see _initAsHostsWithComponents
  108. * @param {string|string[]} components
  109. * @param {boolean} [asArray=false]
  110. * @returns {{type: string, components: string[], asArray: boolean}}
  111. */
  112. function getComponentsHostsConfig(components, asArray) {
  113. if (1 === arguments.length) {
  114. asArray = false;
  115. }
  116. return {
  117. type: 'hosts_with_components',
  118. components: Em.makeArray(components),
  119. asArray: asArray
  120. };
  121. }
  122. /**
  123. * Settings for <code>single_mountpoint</code>-initializer
  124. * Used for configs with value as one of the possible mount points
  125. *
  126. * @see _initAsSingleMountPoint
  127. * @param {string|string[]} components
  128. * @param {string} winReplacer
  129. * @returns {{components: string[], winReplacer: string, type: string}}
  130. */
  131. function getSingleMountPointConfig(components, winReplacer) {
  132. winReplacer = winReplacer || 'default';
  133. return {
  134. components: Em.makeArray(components),
  135. winReplacer: winReplacer,
  136. type: 'single_mountpoint'
  137. }
  138. }
  139. /**
  140. * Settings for <code>multiple_mountpoints</code>-initializer
  141. * Used for configs with value as all of the possible mount points
  142. *
  143. * @see _initAsMultipleMountPoints
  144. * @param {string|string[]} components
  145. * @param {string} winReplacer
  146. * @returns {{components: string[], winReplacer: string, type: string}}
  147. */
  148. function getMultipleMountPointsConfig(components, winReplacer) {
  149. winReplacer = winReplacer || 'default';
  150. return {
  151. components: Em.makeArray(components),
  152. winReplacer: winReplacer,
  153. type: 'multiple_mountpoints'
  154. }
  155. }
  156. /**
  157. * Helper-object used to set initial value for some configs
  158. *
  159. * Usage:
  160. * <pre>
  161. * var configProperty = Object.create({});
  162. * var localDB = {
  163. * hosts: [],
  164. * masterComponentHosts: [],
  165. * slaveComponentHosts: []
  166. * };
  167. * var dependencies = {};
  168. * configPropertyHelper.initialValue(configProperty, localDB, dependencies);
  169. * </pre>
  170. *
  171. * @type {Em.Object}
  172. */
  173. App.ConfigInitializer = App.ConfigInitializerClass.create({
  174. initializers: {
  175. 'dfs.namenode.rpc-address': getSimpleComponentConfig('NAMENODE'),
  176. 'dfs.http.address': getSimpleComponentConfig('NAMENODE'),
  177. 'dfs.namenode.http-address': getSimpleComponentConfig('NAMENODE'),
  178. 'dfs.https.address': getSimpleComponentConfig('NAMENODE'),
  179. 'dfs.namenode.https-address': getSimpleComponentConfig('NAMENODE'),
  180. 'dfs.secondary.http.address': getSimpleComponentConfig('SECONDARY_NAMENODE'),
  181. 'dfs.namenode.secondary.http-address': getSimpleComponentConfig('SECONDARY_NAMENODE'),
  182. 'yarn.resourcemanager.hostname': getSimpleComponentConfig('RESOURCEMANAGER', false),
  183. 'yarn.resourcemanager.resource-tracker.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  184. 'yarn.resourcemanager.webapp.https.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  185. 'yarn.resourcemanager.webapp.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  186. 'yarn.resourcemanager.scheduler.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  187. 'yarn.resourcemanager.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  188. 'yarn.resourcemanager.admin.address': getSimpleComponentConfig('RESOURCEMANAGER'),
  189. 'yarn.timeline-service.webapp.address': getSimpleComponentConfig('APP_TIMELINE_SERVER'),
  190. 'yarn.timeline-service.webapp.https.address': getSimpleComponentConfig('APP_TIMELINE_SERVER'),
  191. 'yarn.timeline-service.address': getSimpleComponentConfig('APP_TIMELINE_SERVER'),
  192. 'mapred.job.tracker': getSimpleComponentConfig('JOBTRACKER'),
  193. 'mapred.job.tracker.http.address': getSimpleComponentConfig('JOBTRACKER'),
  194. 'mapreduce.history.server.http.address': getSimpleComponentConfig('HISTORYSERVER'),
  195. 'hive_hostname': getSimpleComponentConfig('HIVE_SERVER', false),
  196. 'oozie_hostname': getSimpleComponentConfig('OOZIE_SERVER', false),
  197. 'oozie.base.url': getComponentConfigWithAffixes('OOZIE_SERVER', '://'),
  198. 'hawq_dfs_url': getSimpleComponentConfig('NAMENODE'),
  199. 'hawq_rm_yarn_address': getSimpleComponentConfig('RESOURCEMANAGER'),
  200. 'hawq_rm_yarn_scheduler_address': getSimpleComponentConfig('RESOURCEMANAGER'),
  201. 'fs.default.name': getComponentConfigWithAffixes('NAMENODE', '://'),
  202. 'fs.defaultFS': getComponentConfigWithAffixes('NAMENODE', '://'),
  203. 'hbase.rootdir': getComponentConfigWithAffixes('NAMENODE', '://'),
  204. 'instance.volumes': getComponentConfigWithAffixes('NAMENODE', '://'),
  205. 'yarn.log.server.url': getComponentConfigWithAffixes('HISTORYSERVER', '://'),
  206. 'mapreduce.jobhistory.webapp.address': getSimpleComponentConfig('HISTORYSERVER'),
  207. 'mapreduce.jobhistory.address': getSimpleComponentConfig('HISTORYSERVER'),
  208. 'kafka.ganglia.metrics.host': getSimpleComponentConfig('GANGLIA_SERVER', false),
  209. 'hive_master_hosts': getComponentsHostsConfig(['HIVE_METASTORE', 'HIVE_SERVER']),
  210. 'hadoop_host': getSimpleComponentConfig('NAMENODE', false),
  211. 'nimbus.host': getSimpleComponentConfig('NIMBUS', false),
  212. 'nimbus.seeds': getComponentsHostsConfig('NIMBUS', true),
  213. 'storm.zookeeper.servers': getComponentsHostsConfig('ZOOKEEPER_SERVER', true),
  214. 'hawq_master_address_host': getSimpleComponentConfig('HAWQMASTER', false),
  215. 'hawq_standby_address_host': getSimpleComponentConfig('HAWQSTANDBY', false),
  216. '*.broker.url': {
  217. type: 'host_with_component',
  218. component: 'FALCON_SERVER',
  219. modifier: {
  220. type: 'regexp',
  221. regex: 'localhost'
  222. }
  223. },
  224. 'zookeeper.connect': getZKBasedConfig(),
  225. 'hive.zookeeper.quorum': getZKBasedConfig(),
  226. 'templeton.zookeeper.hosts': getZKBasedConfig(),
  227. 'hadoop.registry.zk.quorum': getZKBasedConfig(),
  228. 'hive.cluster.delegation.token.store.zookeeper.connectString': getZKBasedConfig(),
  229. 'instance.zookeeper.host': getZKBasedConfig(),
  230. 'dfs.name.dir': getMultipleMountPointsConfig('NAMENODE', 'file'),
  231. 'dfs.namenode.name.dir': getMultipleMountPointsConfig('NAMENODE', 'file'),
  232. 'dfs.data.dir': getMultipleMountPointsConfig('DATANODE', 'file'),
  233. 'dfs.datanode.data.dir': getMultipleMountPointsConfig('DATANODE', 'file'),
  234. 'yarn.nodemanager.local-dirs': getMultipleMountPointsConfig('NODEMANAGER'),
  235. 'yarn.nodemanager.log-dirs': getMultipleMountPointsConfig('NODEMANAGER'),
  236. 'mapred.local.dir': getMultipleMountPointsConfig(['TASKTRACKER', 'NODEMANAGER']),
  237. 'log.dirs': getMultipleMountPointsConfig('KAFKA_BROKER'),
  238. 'fs.checkpoint.dir': getSingleMountPointConfig('SECONDARY_NAMENODE', 'file'),
  239. 'dfs.namenode.checkpoint.dir': getSingleMountPointConfig('SECONDARY_NAMENODE', 'file'),
  240. 'yarn.timeline-service.leveldb-timeline-store.path': getSingleMountPointConfig('APP_TIMELINE_SERVER'),
  241. 'yarn.timeline-service.leveldb-state-store.path': getSingleMountPointConfig('APP_TIMELINE_SERVER'),
  242. 'dataDir': getSingleMountPointConfig('ZOOKEEPER_SERVER'),
  243. 'oozie_data_dir': getSingleMountPointConfig('OOZIE_SERVER'),
  244. 'storm.local.dir': getSingleMountPointConfig(['NODEMANAGER', 'NIMBUS']),
  245. '*.falcon.graph.storage.directory': getSingleMountPointConfig('FALCON_SERVER'),
  246. '*.falcon.graph.serialize.path': getSingleMountPointConfig('FALCON_SERVER')
  247. },
  248. uniqueInitializers: {
  249. 'hive_database': '_initHiveDatabaseValue',
  250. 'templeton.hive.properties': '_initTempletonHiveProperties',
  251. 'hbase.zookeeper.quorum': '_initHBaseZookeeperQuorum',
  252. 'yarn.resourcemanager.zk-address': '_initYarnRMzkAddress',
  253. 'RANGER_HOST': '_initRangerHost',
  254. 'hive.metastore.uris': '_initHiveMetastoreUris'
  255. },
  256. initializerTypes: {
  257. host_with_component: {
  258. method: '_initAsHostWithComponent'
  259. },
  260. hosts_with_components: {
  261. method: '_initAsHostsWithComponents'
  262. },
  263. zookeeper_based: {
  264. method: '_initAsZookeeperServersList'
  265. },
  266. single_mountpoint: {
  267. method: '_initAsSingleMountPoint'
  268. },
  269. multiple_mountpoints: {
  270. method: '_initAsMultipleMountPoints'
  271. }
  272. },
  273. /**
  274. * Map for methods used as value-modifiers for configProperties with values as mount point(s)
  275. * Used if mount point is win-like (@see winRegex)
  276. * Key: id
  277. * Value: method-name
  278. *
  279. * @type {{default: string, file: string, slashes: string}}
  280. */
  281. winReplacersMap: {
  282. default: '_defaultWinReplace',
  283. file: '_winReplaceWithFile',
  284. slashes: '_defaultWinReplaceWithAdditionalSlashes'
  285. },
  286. /**
  287. * Initializer for configs with value equal to hostName with needed component
  288. * Value example: 'hostName'
  289. *
  290. * @param {Object} configProperty
  291. * @param {topologyLocalDB} localDB
  292. * @param {object} dependencies
  293. * @param {object} initializer
  294. * @returns {Object}
  295. * @private
  296. */
  297. _initAsHostWithComponent: function (configProperty, localDB, dependencies, initializer) {
  298. var component = localDB.masterComponentHosts.findProperty('component', initializer.component);
  299. if (!component) {
  300. return configProperty;
  301. }
  302. if (initializer.modifier) {
  303. var replaceWith = Em.getWithDefault(initializer.modifier, 'prefix', '')
  304. + component.hostName
  305. + Em.getWithDefault(initializer.modifier, 'suffix', '');
  306. this.setRecommendedValue(configProperty, initializer.modifier.regex, replaceWith);
  307. }
  308. else {
  309. configProperty.setProperties({
  310. recommendedValue: component.hostName,
  311. value: component.hostName
  312. })
  313. }
  314. return configProperty;
  315. },
  316. /**
  317. * Initializer for configs with value equal to hostNames with needed components
  318. * May be array or comma-separated list
  319. * Depends on <code>initializer.asArray</code> (true - array, false - string)
  320. * Value example: 'hostName1,hostName2,hostName3' or ['hostName1', 'hostName2', 'hostName3']
  321. *
  322. * @param {Object} configProperty
  323. * @param {topologyLocalDB} localDB
  324. * @param {object} dependencies
  325. * @param {object} initializer
  326. * @return {Object}
  327. * @private
  328. */
  329. _initAsHostsWithComponents: function (configProperty, localDB, dependencies, initializer) {
  330. var hostNames = localDB.masterComponentHosts.filter(function (masterComponent) {
  331. return initializer.components.contains(masterComponent.component);
  332. }).mapProperty('hostName');
  333. if (!initializer.asArray) {
  334. hostNames = hostNames.uniq().join(',');
  335. }
  336. configProperty.setProperties({
  337. value: hostNames,
  338. recommendedValue: hostNames
  339. });
  340. return configProperty;
  341. },
  342. /**
  343. * Unique initializer for <code>hive_database</code>-config
  344. *
  345. * @param {Object} configProperty
  346. * @returns {Object}
  347. * @private
  348. */
  349. _initHiveDatabaseValue: function (configProperty) {
  350. var newMySQLDBOption = configProperty.get('options').findProperty('displayName', 'New MySQL Database');
  351. if (newMySQLDBOption) {
  352. var isNewMySQLDBOptionHidden = !App.get('supports.alwaysEnableManagedMySQLForHive') && App.get('router.currentState.name') != 'configs' &&
  353. !App.get('isManagedMySQLForHiveEnabled');
  354. if (isNewMySQLDBOptionHidden && configProperty.get('value') == 'New MySQL Database') {
  355. configProperty.set('value', 'Existing MySQL Database');
  356. }
  357. Em.set(newMySQLDBOption, 'hidden', isNewMySQLDBOptionHidden);
  358. }
  359. return configProperty;
  360. },
  361. /**
  362. * Initializer for configs with value equal to hostNames-list where ZOOKEEPER_SERVER is installed
  363. * Value example: 'host1:2020,host2:2020,host3:2020'
  364. *
  365. * @param {Object} configProperty
  366. * @param {topologyLocalDB} localDB
  367. * @returns {Object}
  368. * @private
  369. */
  370. _initAsZookeeperServersList: function (configProperty, localDB) {
  371. var zkHosts = localDB.masterComponentHosts.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
  372. var zkHostPort = zkHosts;
  373. var regex = '\\w*:(\\d+)'; //regex to fetch the port
  374. var portValue = configProperty.get('recommendedValue') && configProperty.get('recommendedValue').match(new RegExp(regex));
  375. if (!portValue) {
  376. return configProperty;
  377. }
  378. if (portValue[1]) {
  379. for ( var i = 0; i < zkHosts.length; i++ ) {
  380. zkHostPort[i] = zkHosts[i] + ':' + portValue[1];
  381. }
  382. }
  383. this.setRecommendedValue(configProperty, '(.*)', zkHostPort);
  384. return configProperty;
  385. },
  386. /**
  387. * Unique initializer for <code>templeton.hive.properties</code>
  388. *
  389. * @param {Object} configProperty
  390. * @param {topologyLocalDB} localDB
  391. * @param {object} dependencies
  392. * @returns {Object}
  393. * @private
  394. */
  395. _initTempletonHiveProperties: function (configProperty, localDB, dependencies) {
  396. var hiveMSUris = this.getHiveMetastoreUris(localDB.masterComponentHosts, dependencies['hive.metastore.uris']).replace(',', '\\,');
  397. if (/\/\/localhost:/g.test(configProperty.get('value'))) {
  398. configProperty.set('recommendedValue', configProperty.get('value') + ',hive.metastore.execute.setugi=true');
  399. }
  400. this.setRecommendedValue(configProperty, "(hive\\.metastore\\.uris=)([^\\,]+)", "$1" + hiveMSUris);
  401. return configProperty;
  402. },
  403. /**
  404. * Unique initializer for <code>hbase.zookeeper.quorum</code>
  405. *
  406. * @param {Object} configProperty
  407. * @param {topologyLocalDB} localDB
  408. * @returns {Object}
  409. * @private
  410. */
  411. _initHBaseZookeeperQuorum: function (configProperty, localDB) {
  412. if (configProperty.get('filename') == 'hbase-site.xml') {
  413. var zkHosts = localDB.masterComponentHosts.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
  414. this.setRecommendedValue(configProperty, "(.*)", zkHosts);
  415. }
  416. return configProperty;
  417. },
  418. /**
  419. * Unique initializer for <code>RANGER_HOST</code>
  420. * If RANGER_ADMIN-component isn't installed, this config becomes unneeded (isVisible - false, isRequired - false)
  421. * Value example: 'hostName'
  422. *
  423. * @param {Object} configProperty
  424. * @param {topologyLocalDB} localDB
  425. * @returns {Object}
  426. * @private
  427. */
  428. _initRangerHost: function (configProperty, localDB) {
  429. var rangerAdminHost = localDB.masterComponentHosts.findProperty('component', 'RANGER_ADMIN');
  430. if(rangerAdminHost) {
  431. configProperty.setProperties({
  432. value: rangerAdminHost.hostName,
  433. recommendedValue: rangerAdminHost.hostName
  434. });
  435. }
  436. else {
  437. configProperty.setProperties({
  438. isVisible: 'false',
  439. isRequired: 'false'
  440. });
  441. }
  442. return configProperty;
  443. },
  444. /**
  445. * Unique initializer for <code>yarn.resourcemanager.zk-address</code>
  446. * List of hosts where ZOOKEEPER_SERVER is installed
  447. * Port is taken from <code>dependencies.clientPort</code>
  448. * Value example: 'host1:111,host2:111,host3:111'
  449. *
  450. * @param {Object} configProperty
  451. * @param {topologyLocalDB} localDB
  452. * @param {object} dependencies
  453. * @returns {Object}
  454. * @private
  455. */
  456. _initYarnRMzkAddress: function (configProperty, localDB, dependencies) {
  457. var value = localDB.masterComponentHosts.filterProperty('component', 'ZOOKEEPER_SERVER').map(function (component) {
  458. return component.hostName + ':' + dependencies.clientPort
  459. }).join(',');
  460. configProperty.setProperties({
  461. value: value,
  462. recommendedValue: value
  463. });
  464. return configProperty;
  465. },
  466. /**
  467. * Unique initializer for <code>hive.metastore.uris</code>
  468. *
  469. * @param {Object} configProperty
  470. * @param {topologyLocalDB} localDB
  471. * @param {object} dependencies
  472. * @returns {Object}
  473. * @private
  474. */
  475. _initHiveMetastoreUris: function (configProperty, localDB, dependencies) {
  476. var hiveMSUris = this.getHiveMetastoreUris(localDB.masterComponentHosts, dependencies['hive.metastore.uris']);
  477. if (hiveMSUris) {
  478. this.setRecommendedValue(configProperty, "(.*)", hiveMSUris);
  479. }
  480. return configProperty;
  481. },
  482. /**
  483. * Get hive.metastore.uris initial value
  484. *
  485. * @param {object[]} hosts
  486. * @param {string} recommendedValue
  487. * @returns {string}
  488. */
  489. getHiveMetastoreUris: function (hosts, recommendedValue) {
  490. var hiveMSHosts = hosts.filterProperty('component', 'HIVE_METASTORE').mapProperty('hostName'),
  491. hiveMSUris = hiveMSHosts,
  492. regex = "\\w*:(\\d+)",
  493. portValue = recommendedValue && recommendedValue.match(new RegExp(regex));
  494. if (!portValue) {
  495. return '';
  496. }
  497. if (portValue[1]) {
  498. for (var i = 0; i < hiveMSHosts.length; i++) {
  499. hiveMSUris[i] = "thrift://" + hiveMSHosts[i] + ":" + portValue[1];
  500. }
  501. }
  502. return hiveMSUris.join(',');
  503. },
  504. /**
  505. * Set <code>value</code> and <code>recommendedValue</code> for <code>configProperty</code>
  506. * basing on <code>recommendedValue</code> with replacing <code>regex</code> for <code>replaceWith</code>
  507. *
  508. * @param {Object} configProperty
  509. * @param {string} regex
  510. * @param {string} replaceWith
  511. * @return {Object}
  512. */
  513. setRecommendedValue: function (configProperty, regex, replaceWith) {
  514. var recommendedValue = Em.isNone(configProperty.get('recommendedValue')) ? '' : configProperty.get('recommendedValue');
  515. var re = new RegExp(regex);
  516. recommendedValue = recommendedValue.replace(re, replaceWith);
  517. configProperty.set('recommendedValue', recommendedValue);
  518. configProperty.set('value', Em.isNone(configProperty.get('recommendedValue')) ? '' : configProperty.get('recommendedValue'));
  519. return configProperty;
  520. },
  521. /**
  522. * Initializer for configs with value as one of the possible mount points
  523. * Only hosts that contains on the components from <code>initializer.components</code> are processed
  524. * Hosts with Windows needs additional processing (@see winReplacersMap)
  525. * Value example: '/', '/some/cool/dir'
  526. *
  527. * @param {Object} configProperty
  528. * @param {topologyLocalDB} localDB
  529. * @param {object} dependencies
  530. * @param {object} initializer
  531. * @return {Object}
  532. */
  533. _initAsSingleMountPoint: function (configProperty, localDB, dependencies, initializer) {
  534. var hostsInfo = this._updateHostInfo(localDB.hosts);
  535. var setOfHostNames = this._getSetOfHostNames(localDB, initializer);
  536. var winReplacersMap = this.get('winReplacersMap');
  537. // In Add Host Wizard, if we did not select this slave component for any host, then we don't process any further.
  538. if (!setOfHostNames.length) {
  539. return configProperty;
  540. }
  541. var allMountPoints = this._getAllMountPoints(setOfHostNames, hostsInfo);
  542. var mPoint = allMountPoints[0].mountpoint;
  543. if (mPoint === "/") {
  544. mPoint = configProperty.get('recommendedValue');
  545. }
  546. else {
  547. var mp = mPoint.toLowerCase();
  548. if (winRegex.test(mp)) {
  549. var methodName = winReplacersMap[initializer.winReplacer];
  550. mPoint = this[methodName].call(this, configProperty, mp);
  551. }
  552. else {
  553. mPoint = mPoint + configProperty.get('recommendedValue');
  554. }
  555. }
  556. configProperty.setProperties({
  557. value: mPoint,
  558. recommendedValue: mPoint
  559. });
  560. return configProperty;
  561. },
  562. /**
  563. * Initializer for configs with value as all of the possible mount points
  564. * Only hosts that contains on the components from <code>initializer.components</code> are processed
  565. * Hosts with Windows needs additional processing (@see winReplacersMap)
  566. * Value example: '/\n/some/cool/dir' (`\n` - is divider)
  567. *
  568. * @param {Object} configProperty
  569. * @param {topologyLocalDB} localDB
  570. * @param {object} dependencies
  571. * @param {object} initializer
  572. * @return {Object}
  573. */
  574. _initAsMultipleMountPoints: function (configProperty, localDB, dependencies, initializer) {
  575. var hostsInfo = this._updateHostInfo(localDB.hosts);
  576. var self = this;
  577. var setOfHostNames = this._getSetOfHostNames(localDB, initializer);
  578. var winReplacersMap = this.get('winReplacersMap');
  579. // In Add Host Wizard, if we did not select this slave component for any host, then we don't process any further.
  580. if (!setOfHostNames.length) {
  581. return configProperty;
  582. }
  583. var allMountPoints = this._getAllMountPoints(setOfHostNames, hostsInfo);
  584. var mPoint = '';
  585. allMountPoints.forEach(function (eachDrive) {
  586. if (eachDrive.mountpoint === '/') {
  587. mPoint += configProperty.get('recommendedValue') + "\n";
  588. }
  589. else {
  590. var mp = eachDrive.mountpoint.toLowerCase();
  591. if (winRegex.test(mp)) {
  592. var methodName = winReplacersMap[initializer.winReplacer];
  593. mPoint += self[methodName].call(this, configProperty, mp);
  594. }
  595. else {
  596. mPoint += eachDrive.mountpoint + configProperty.get('recommendedValue') + "\n";
  597. }
  598. }
  599. }, this);
  600. configProperty.setProperties({
  601. value: mPoint,
  602. recommendedValue: mPoint
  603. });
  604. return configProperty;
  605. },
  606. /**
  607. * Replace drive-based windows-path with 'file:///'
  608. *
  609. * @param {Object} configProperty
  610. * @param {string} mountPoint
  611. * @returns {string}
  612. * @private
  613. */
  614. _winReplaceWithFile: function (configProperty, mountPoint) {
  615. var winDriveUrl = mountPoint.toLowerCase().replace(winRegex, 'file:///$1:');
  616. return winDriveUrl + configProperty.get('recommendedValue') + '\n';
  617. },
  618. /**
  619. * Replace drive-based windows-path
  620. *
  621. * @param {Object} configProperty
  622. * @param {string} mountPoint
  623. * @returns {string}
  624. * @private
  625. */
  626. _defaultWinReplace: function (configProperty, mountPoint) {
  627. var winDrive = mountPoint.toLowerCase().replace(winRegex, '$1:');
  628. var winDir = configProperty.get('recommendedValue').replace(/\//g, '\\');
  629. return winDrive + winDir + '\n';
  630. },
  631. /**
  632. * Same to <code>_defaultWinReplace</code>, but with extra-slash in the end
  633. *
  634. * @param {Object} configProperty
  635. * @param {string} mountPoint
  636. * @returns {string}
  637. * @private
  638. */
  639. _defaultWinReplaceWithAdditionalSlashes: function (configProperty, mountPoint) {
  640. var winDrive = mountPoint.toLowerCase().replace(winRegex, '$1:');
  641. var winDir = configProperty.get('recommendedValue').replace(/\//g, '\\\\');
  642. return winDrive + winDir + '\n';
  643. },
  644. /**
  645. * Update information from localDB using <code>App.Host</code>-model
  646. *
  647. * @param {object} hostsInfo
  648. * @returns {object}
  649. * @private
  650. */
  651. _updateHostInfo: function (hostsInfo) {
  652. App.Host.find().forEach(function (item) {
  653. if (!hostsInfo[item.get('id')]) {
  654. hostsInfo[item.get('id')] = {
  655. name: item.get('id'),
  656. cpu: item.get('cpu'),
  657. memory: item.get('memory'),
  658. disk_info: item.get('diskInfo'),
  659. bootStatus: "REGISTERED",
  660. isInstalled: true
  661. };
  662. }
  663. });
  664. return hostsInfo;
  665. },
  666. /**
  667. * Determines if mount point is valid
  668. * Criterias:
  669. * <ul>
  670. * <li>Should has available space</li>
  671. * <li>Should not be home-dir</li>
  672. * <li>Should not be docker-dir</li>
  673. * <li>Should not be boot-dir</li>
  674. * <li>Should not be dev-dir</li>
  675. * </ul>
  676. *
  677. * @param {{mountpoint: string, available: number}} mPoint
  678. * @returns {boolean} true - valid, false - invalid
  679. * @private
  680. */
  681. _filterMountPoint: function (mPoint) {
  682. var isAvailable = mPoint.available !== 0;
  683. if (!isAvailable) {
  684. return false;
  685. }
  686. var notHome = !['/', '/home'].contains(mPoint.mountpoint);
  687. var notDocker = !['/etc/resolv.conf', '/etc/hostname', '/etc/hosts'].contains(mPoint.mountpoint);
  688. var notBoot = mPoint.mountpoint && !(mPoint.mountpoint.startsWith('/boot') || mPoint.mountpoint.startsWith('/mnt'));
  689. var notDev = !(['devtmpfs', 'tmpfs', 'vboxsf', 'CDFS'].contains(mPoint.type));
  690. return notHome && notDocker && notBoot && notDev;
  691. },
  692. /**
  693. * Get list of hostNames from localDB which contains needed components
  694. *
  695. * @param {topologyLocalDB} localDB
  696. * @param {object} initializer
  697. * @returns {string[]}
  698. * @private
  699. */
  700. _getSetOfHostNames: function (localDB, initializer) {
  701. var masterComponentHostsInDB = localDB.masterComponentHosts;
  702. var slaveComponentHostsInDB = localDB.slaveComponentHosts;
  703. var hosts = masterComponentHostsInDB.filter(function (master) {
  704. return initializer.components.contains(master.component);
  705. }).mapProperty('hostName');
  706. var sHosts = slaveComponentHostsInDB.find(function (slave) {
  707. return initializer.components.contains(slave.componentName);
  708. });
  709. if (sHosts) {
  710. hosts = hosts.concat(sHosts.hosts.mapProperty('hostName'));
  711. }
  712. return hosts;
  713. },
  714. /**
  715. * Get list of all unique valid mount points for hosts
  716. *
  717. * @param {string[]} setOfHostNames
  718. * @param {object} hostsInfo
  719. * @returns {string[]}
  720. * @private
  721. */
  722. _getAllMountPoints: function (setOfHostNames, hostsInfo) {
  723. var allMountPoints = [];
  724. for (var i = 0; i < setOfHostNames.length; i++) {
  725. var hostname = setOfHostNames[i];
  726. var mountPointsPerHost = hostsInfo[hostname].disk_info;
  727. var mountPointAsRoot = mountPointsPerHost.findProperty('mountpoint', '/');
  728. // If Server does not send any host details information then atleast one mountpoint should be presumed as root
  729. // This happens in a single container Linux Docker environment.
  730. if (!mountPointAsRoot) {
  731. mountPointAsRoot = {
  732. mountpoint: '/'
  733. };
  734. }
  735. mountPointsPerHost.filter(this._filterMountPoint).forEach(function (mPoint) {
  736. if( !allMountPoints.findProperty("mountpoint", mPoint.mountpoint)) {
  737. allMountPoints.push(mPoint);
  738. }
  739. }, this);
  740. }
  741. if (!allMountPoints.length) {
  742. allMountPoints.push(mountPointAsRoot);
  743. }
  744. return allMountPoints;
  745. }
  746. });