step4_controller.js 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  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. /**
  20. * Additional data that is used in the `Move Component Initializers`
  21. *
  22. * @typedef {object} reassignComponentDependencies
  23. * @property {string} sourceHostName host where component was before moving
  24. * @property {string} targetHostName host where component will be after moving
  25. */
  26. App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageController.extend(App.WizardEnableDone, {
  27. name: "reassignMasterWizardStep4Controller",
  28. commands: [
  29. 'stopRequiredServices',
  30. 'cleanMySqlServer',
  31. 'createHostComponents',
  32. 'putHostComponentsInMaintenanceMode',
  33. 'reconfigure',
  34. 'installHostComponents',
  35. 'startZooKeeperServers',
  36. 'startNameNode',
  37. 'deleteHostComponents',
  38. 'configureMySqlServer',
  39. 'startMySqlServer',
  40. 'startNewMySqlServer',
  41. 'startRequiredServices'
  42. ],
  43. // custom commands for Components with DB Configuration and Check
  44. commandsForDB: [
  45. 'createHostComponents',
  46. 'installHostComponents',
  47. 'configureMySqlServer',
  48. 'restartMySqlServer',
  49. 'testDBConnection',
  50. 'stopRequiredServices',
  51. 'cleanMySqlServer',
  52. 'putHostComponentsInMaintenanceMode',
  53. 'reconfigure',
  54. 'deleteHostComponents',
  55. 'configureMySqlServer',
  56. 'startRequiredServices'
  57. ],
  58. clusterDeployState: 'REASSIGN_MASTER_INSTALLING',
  59. multiTaskCounter: 0,
  60. hostComponents: [],
  61. /**
  62. * List of components, that do not need reconfiguration for moving to another host
  63. * Reconfigure command will be skipped
  64. */
  65. componentsWithoutReconfiguration: ['METRICS_COLLECTOR'],
  66. /**
  67. * Map with lists of unrelated services.
  68. * Used to define list of services to stop/start.
  69. */
  70. unrelatedServicesMap: {
  71. 'JOBTRACKER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  72. 'RESOURCEMANAGER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  73. 'APP_TIMELINE_SERVER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  74. 'OOZIE_SERVER': ['ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM', 'HIVE'],
  75. 'WEBHCAT_SERVER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  76. 'HIVE_SERVER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  77. 'HIVE_METASTORE': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'],
  78. 'MYSQL_SERVER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM']
  79. },
  80. dbPropertyMap: {
  81. 'HIVE_SERVER': 'javax.jdo.option.ConnectionDriverName',
  82. 'HIVE_METASTORE': 'javax.jdo.option.ConnectionDriverName',
  83. 'OOZIE_SERVER': 'oozie.service.JPAService.jdbc.url'
  84. },
  85. /**
  86. * additional configs with template values
  87. * Part of value to substitute has following format: "<replace-value>"
  88. */
  89. additionalConfigsMap: [
  90. {
  91. componentName: 'RESOURCEMANAGER',
  92. configs: {
  93. 'yarn-site': {
  94. 'yarn.resourcemanager.address': '<replace-value>:8050',
  95. 'yarn.resourcemanager.admin.address': '<replace-value>:8141',
  96. 'yarn.resourcemanager.resource-tracker.address': '<replace-value>:8025',
  97. 'yarn.resourcemanager.scheduler.address': '<replace-value>:8030',
  98. 'yarn.resourcemanager.webapp.address': '<replace-value>:8088',
  99. 'yarn.resourcemanager.hostname': '<replace-value>'
  100. }
  101. }
  102. },
  103. {
  104. componentName: 'JOBTRACKER',
  105. configs: {
  106. 'mapred-site': {
  107. 'mapred.job.tracker.http.address': '<replace-value>:50030',
  108. 'mapred.job.tracker': '<replace-value>:50300'
  109. }
  110. }
  111. },
  112. {
  113. componentName: 'SECONDARY_NAMENODE',
  114. configs: {
  115. 'hdfs-site': {
  116. 'dfs.secondary.http.address': '<replace-value>:50090'
  117. }
  118. },
  119. configs_Hadoop2: {
  120. 'hdfs-site': {
  121. 'dfs.namenode.secondary.http-address': '<replace-value>:50090'
  122. }
  123. }
  124. },
  125. {
  126. componentName: 'NAMENODE',
  127. configs: {
  128. 'hdfs-site': {
  129. 'dfs.http.address': '<replace-value>:50070',
  130. 'dfs.https.address': '<replace-value>:50470'
  131. },
  132. 'core-site': {
  133. 'fs.default.name': 'hdfs://<replace-value>:8020'
  134. }
  135. },
  136. configs_Hadoop2: {
  137. 'hdfs-site': {
  138. 'dfs.namenode.rpc-address': '<replace-value>:8020',
  139. 'dfs.namenode.http-address': '<replace-value>:50070',
  140. 'dfs.namenode.https-address': '<replace-value>:50470'
  141. },
  142. 'core-site': {
  143. 'fs.defaultFS': 'hdfs://<replace-value>:8020'
  144. }
  145. }
  146. },
  147. {
  148. componentName: 'APP_TIMELINE_SERVER',
  149. configs: {
  150. 'yarn-site': {
  151. 'yarn.timeline-service.webapp.address': '<replace-value>:8188',
  152. 'yarn.timeline-service.webapp.https.address': '<replace-value>:8190',
  153. 'yarn.timeline-service.address': '<replace-value>:10200'
  154. }
  155. }
  156. },
  157. {
  158. componentName: 'OOZIE_SERVER',
  159. configs: {
  160. 'oozie-site': {
  161. 'oozie.base.url': 'http://<replace-value>:11000/oozie'
  162. },
  163. 'core-site': {
  164. 'hadoop.proxyuser.oozie.hosts': '<replace-value>'
  165. }
  166. }
  167. },
  168. {
  169. componentName: 'HIVE_METASTORE',
  170. configs: {
  171. 'hive-site': {}
  172. }
  173. },
  174. {
  175. componentName: 'MYSQL_SERVER',
  176. configs: {
  177. 'hive-site': {
  178. 'javax.jdo.option.ConnectionURL': 'jdbc:mysql://<replace-value>/hive?createDatabaseIfNotExist=true'
  179. }
  180. }
  181. },
  182. {
  183. componentName: 'HISTORYSERVER',
  184. configs: {
  185. 'mapred-site': {
  186. 'mapreduce.jobhistory.webapp.address': '<replace-value>:19888',
  187. 'mapreduce.jobhistory.address': '<replace-value>:10020'
  188. }
  189. }
  190. }
  191. ],
  192. secureConfigsMap: [
  193. {
  194. componentName: 'NAMENODE',
  195. configs: [
  196. {
  197. site: 'hdfs-site',
  198. keytab: 'dfs.namenode.keytab.file',
  199. principal: 'dfs.namenode.kerberos.principal'
  200. },
  201. {
  202. site: 'hdfs-site',
  203. keytab: 'dfs.web.authentication.kerberos.keytab',
  204. principal: 'dfs.web.authentication.kerberos.principal'
  205. }
  206. ]
  207. },
  208. {
  209. componentName: 'SECONDARY_NAMENODE',
  210. configs: [
  211. {
  212. site: 'hdfs-site',
  213. keytab: 'dfs.secondary.namenode.keytab.file',
  214. principal: 'dfs.secondary.namenode.kerberos.principal'
  215. },
  216. {
  217. site: 'hdfs-site',
  218. keytab: 'dfs.web.authentication.kerberos.keytab',
  219. principal: 'dfs.web.authentication.kerberos.principal'
  220. }
  221. ]
  222. },
  223. {
  224. componentName: 'RESOURCEMANAGER',
  225. configs: [
  226. {
  227. site: 'yarn-site',
  228. keytab: 'yarn.resourcemanager.keytab',
  229. principal: 'yarn.resourcemanager.principal'
  230. },
  231. {
  232. site: 'yarn-site',
  233. keytab: 'yarn.resourcemanager.webapp.spnego-keytab-file',
  234. principal: 'yarn.resourcemanager.webapp.spnego-principal'
  235. }
  236. ]
  237. },
  238. {
  239. componentName: 'OOZIE_SERVER',
  240. configs: [
  241. {
  242. site: 'oozie-site',
  243. keytab: 'oozie.authentication.kerberos.keytab',
  244. principal: 'oozie.authentication.kerberos.principal'
  245. },
  246. {
  247. site: 'oozie-site',
  248. keytab: 'oozie.service.HadoopAccessorService.keytab.file',
  249. principal: 'oozie.service.HadoopAccessorService.kerberos.principal'
  250. }
  251. ]
  252. },
  253. {
  254. componentName: 'WEBHCAT_SERVER',
  255. configs: [
  256. {
  257. site: 'webhcat-site',
  258. keytab: 'templeton.kerberos.keytab',
  259. principal: 'templeton.kerberos.principal'
  260. }
  261. ]
  262. },
  263. {
  264. componentName: 'HIVE_SERVER',
  265. configs: [
  266. {
  267. site: 'hive-site',
  268. keytab: 'hive.server2.authentication.kerberos.keytab',
  269. principal: 'hive.server2.authentication.kerberos.principal'
  270. },
  271. {
  272. site: 'hive-site',
  273. keytab: 'hive.server2.authentication.spnego.keytab',
  274. principal: 'hive.server2.authentication.spnego.principal'
  275. }
  276. ]
  277. },
  278. {
  279. componentName: 'HIVE_METASTORE',
  280. configs: [
  281. {
  282. site: 'hive-site',
  283. keytab: 'hive.metastore.kerberos.keytab.file',
  284. principal: 'hive.metastore.kerberos.principal'
  285. }
  286. ]
  287. }
  288. ],
  289. /**
  290. * set additional configs
  291. * configs_Hadoop2 - configs which belongs to Hadoop 2 stack only
  292. * @param configs
  293. * @param componentName
  294. * @param replaceValue
  295. * @return {Boolean}
  296. */
  297. setAdditionalConfigs: function (configs, componentName, replaceValue) {
  298. var component = this.get('additionalConfigsMap').findProperty('componentName', componentName);
  299. if (Em.isNone(component)) return false;
  300. var additionalConfigs = (component.configs_Hadoop2) ? component.configs_Hadoop2 : component.configs;
  301. for (var site in additionalConfigs) {
  302. if (additionalConfigs.hasOwnProperty(site)) {
  303. for (var property in additionalConfigs[site]) {
  304. if (additionalConfigs[site].hasOwnProperty(property)) {
  305. if (App.get('isHaEnabled') && componentName === 'NAMENODE' && (property === 'fs.defaultFS' || property === 'dfs.namenode.rpc-address')) continue;
  306. configs[site][property] = additionalConfigs[site][property].replace('<replace-value>', replaceValue);
  307. }
  308. }
  309. }
  310. }
  311. return true;
  312. },
  313. /**
  314. * load step info
  315. */
  316. loadStep: function () {
  317. if (this.get('content.reassign.component_name') === 'NAMENODE' && App.get('isHaEnabled')) {
  318. this.set('hostComponents', ['NAMENODE', 'ZKFC']);
  319. } else {
  320. this.set('hostComponents', [this.get('content.reassign.component_name')]);
  321. }
  322. this.set('serviceName', [this.get('content.reassign.service_id')]);
  323. this._super();
  324. },
  325. /**
  326. * concat host-component names into string
  327. * @return {String}
  328. */
  329. getHostComponentsNames: function () {
  330. var hostComponentsNames = '';
  331. this.get('hostComponents').forEach(function (comp, index) {
  332. hostComponentsNames += index ? '+' : '';
  333. hostComponentsNames += comp === 'ZKFC' ? comp : App.format.role(comp);
  334. }, this);
  335. return hostComponentsNames;
  336. },
  337. /**
  338. * remove unneeded tasks
  339. */
  340. removeUnneededTasks: function () {
  341. var componentName = this.get('content.reassign.component_name');
  342. if (this.isComponentWithDB()) {
  343. var db_type = this.get('content.databaseType');
  344. var is_remote_db = this.get('content.serviceProperties.is_remote_db');
  345. if (is_remote_db || db_type !== 'mysql') {
  346. this.removeTasks(['configureMySqlServer', 'startMySqlServer', 'restartMySqlServer', 'cleanMySqlServer', 'configureMySqlServer']);
  347. }
  348. if (db_type === 'derby') {
  349. this.removeTasks(['testDBConnection']);
  350. }
  351. }
  352. if (componentName !== 'MYSQL_SERVER' && !this.isComponentWithDB()) {
  353. this.removeTasks(['configureMySqlServer', 'startMySqlServer', 'restartMySqlServer', 'cleanMySqlServer', 'startNewMySqlServer', 'configureMySqlServer']);
  354. }
  355. if (componentName === 'MYSQL_SERVER') {
  356. this.removeTasks(['cleanMySqlServer']);
  357. }
  358. if (this.get('content.hasManualSteps')) {
  359. if (componentName === 'NAMENODE' && App.get('isHaEnabled')) {
  360. // Only for reassign NameNode with HA enabled
  361. this.removeTasks(['deleteHostComponents', 'startRequiredServices']);
  362. } else {
  363. this.removeTasks(['startZooKeeperServers', 'startNameNode', 'deleteHostComponents', 'startRequiredServices']);
  364. }
  365. } else {
  366. this.removeTasks(['startZooKeeperServers', 'startNameNode']);
  367. }
  368. if (this.get('componentsWithoutReconfiguration').contains(componentName)) {
  369. this.removeTasks(['reconfigure']);
  370. }
  371. },
  372. /**
  373. * remove tasks by command name
  374. */
  375. removeTasks: function(commands) {
  376. var tasks = this.get('tasks');
  377. commands.forEach(function(command) {
  378. var cmd = tasks.filterProperty('command', command);
  379. var index = null;
  380. if (cmd.length === 0) {
  381. return false;
  382. } else {
  383. index = tasks.indexOf( cmd[0] );
  384. }
  385. tasks.splice( index, 1 );
  386. });
  387. },
  388. /**
  389. * initialize tasks
  390. */
  391. initializeTasks: function () {
  392. var commands = this.get('commands');
  393. var currentStep = App.router.get('reassignMasterController.currentStep');
  394. var hostComponentsNames = this.getHostComponentsNames();
  395. if (this.isComponentWithDB()) {
  396. commands = this.get('commandsForDB');
  397. }
  398. for (var i = 0; i < commands.length; i++) {
  399. var TaskLabel = i === 3 ? this.get('serviceName') : hostComponentsNames; //For Reconfigure task, show serviceName
  400. var title = Em.I18n.t('services.reassign.step4.tasks.' + commands[i] + '.title').format(TaskLabel);
  401. this.get('tasks').pushObject(Ember.Object.create({
  402. title: title,
  403. status: 'PENDING',
  404. id: i,
  405. command: commands[i],
  406. showRetry: false,
  407. showRollback: false,
  408. name: title,
  409. displayName: title,
  410. progress: 0,
  411. isRunning: false,
  412. hosts: []
  413. }));
  414. }
  415. this.removeUnneededTasks();
  416. this.set('isLoaded', true);
  417. },
  418. hideRollbackButton: function () {
  419. var failedTask = this.get('tasks').findProperty('showRollback');
  420. if (failedTask) {
  421. failedTask.set('showRollback', false);
  422. }
  423. }.observes('tasks.@each.showRollback'),
  424. onComponentsTasksSuccess: function () {
  425. this.incrementProperty('multiTaskCounter');
  426. if (this.get('multiTaskCounter') >= this.get('hostComponents').length) {
  427. this.onTaskCompleted();
  428. }
  429. },
  430. /**
  431. * make server call to stop services
  432. */
  433. stopRequiredServices: function () {
  434. this.stopServices(this.get('unrelatedServicesMap')[this.get('content.reassign.component_name')]);
  435. },
  436. createHostComponents: function () {
  437. this.set('multiTaskCounter', 0);
  438. var hostComponents = this.get('hostComponents');
  439. var hostName = this.get('content.reassignHosts.target');
  440. for (var i = 0; i < hostComponents.length; i++) {
  441. this.createComponent(hostComponents[i], hostName, this.get('content.reassign.service_id'));
  442. }
  443. },
  444. onCreateComponent: function () {
  445. this.onComponentsTasksSuccess();
  446. },
  447. putHostComponentsInMaintenanceMode: function () {
  448. this.set('multiTaskCounter', 0);
  449. var hostComponents = this.get('hostComponents');
  450. var hostName = this.get('content.reassignHosts.source');
  451. for (var i = 0; i < hostComponents.length; i++) {
  452. App.ajax.send({
  453. name: 'common.host.host_component.passive',
  454. sender: this,
  455. data: {
  456. hostName: hostName,
  457. passive_state: "ON",
  458. componentName: hostComponents[i]
  459. },
  460. success: 'onComponentsTasksSuccess',
  461. error: 'onTaskError'
  462. });
  463. }
  464. },
  465. installHostComponents: function () {
  466. this.set('multiTaskCounter', 0);
  467. var hostComponents = this.get('hostComponents');
  468. var hostName = this.get('content.reassignHosts.target');
  469. for (var i = 0; i < hostComponents.length; i++) {
  470. this.updateComponent(hostComponents[i], hostName, this.get('content.reassign.service_id'), "Install", hostComponents.length);
  471. }
  472. },
  473. reconfigure: function () {
  474. this.loadConfigsTags();
  475. },
  476. loadConfigsTags: function () {
  477. App.ajax.send({
  478. name: 'config.tags',
  479. sender: this,
  480. success: 'onLoadConfigsTags',
  481. error: 'onTaskError'
  482. });
  483. },
  484. serviceToConfigSiteMap: {
  485. 'NAMENODE': ['hdfs-site', 'core-site'],
  486. 'SECONDARY_NAMENODE': ['hdfs-site', 'core-site'],
  487. 'JOBTRACKER': ['mapred-site'],
  488. 'RESOURCEMANAGER': ['yarn-site'],
  489. 'WEBHCAT_SERVER': ['webhcat-site'],
  490. 'APP_TIMELINE_SERVER': ['yarn-site', 'yarn-env'],
  491. 'OOZIE_SERVER': ['oozie-site', 'core-site', 'oozie-env'],
  492. 'HIVE_SERVER': ['hive-site', 'webhcat-site', 'hive-env', 'core-site'],
  493. 'HIVE_METASTORE': ['hive-site', 'webhcat-site', 'hive-env', 'core-site'],
  494. 'MYSQL_SERVER': ['hive-site'],
  495. 'HISTORYSERVER': ['mapred-site']
  496. },
  497. /**
  498. * construct URL parameters for config call
  499. * @param componentName
  500. * @param data
  501. * @return {Array}
  502. */
  503. getConfigUrlParams: function (componentName, data) {
  504. var urlParams = [];
  505. this.get('serviceToConfigSiteMap')[componentName].forEach(function(site){
  506. urlParams.push('(type=' + site + '&tag=' + data.Clusters.desired_configs[site].tag + ')');
  507. });
  508. // specific cases for NameNode component
  509. if (componentName === 'NAMENODE') {
  510. if (App.Service.find().someProperty('serviceName', 'HBASE')) {
  511. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  512. }
  513. if (App.Service.find().someProperty('serviceName', 'ACCUMULO')) {
  514. urlParams.push('(type=accumulo-site&tag=' + data.Clusters.desired_configs['accumulo-site'].tag + ')');
  515. }
  516. }
  517. return urlParams;
  518. },
  519. onLoadConfigsTags: function (data) {
  520. var urlParams = this.getConfigUrlParams(this.get('content.reassign.component_name'), data);
  521. App.ajax.send({
  522. name: 'reassign.load_configs',
  523. sender: this,
  524. data: {
  525. urlParams: urlParams.join('|')
  526. },
  527. success: 'onLoadConfigs',
  528. error: 'onTaskError'
  529. });
  530. },
  531. /**
  532. *
  533. * @returns {extendedTopologyLocalDB}
  534. * @private
  535. * @method _prepareTopologyDB
  536. */
  537. _prepareTopologyDB: function () {
  538. var ret = this.get('content').getProperties(['masterComponentHosts', 'slaveComponentHosts', 'hosts']);
  539. ret.installedServices = App.Service.find().mapProperty('serviceName');
  540. return ret;
  541. },
  542. /**
  543. * Create dependencies for Config Initializers
  544. *
  545. * @param {object} additionalDependencies some additional information that should be added
  546. * @returns {reassignComponentDependencies}
  547. * @private
  548. * @method _prepareDependencies
  549. */
  550. _prepareDependencies: function (additionalDependencies) {
  551. additionalDependencies = additionalDependencies || {};
  552. var ret = {};
  553. ret.sourceHostName = this.get('content.reassignHosts.source');
  554. ret.targetHostName = this.get('content.reassignHosts.target');
  555. return Em.merge(ret, additionalDependencies);
  556. },
  557. /**
  558. * Get additional dependencies-data for App.MoveRmConfigInitializer
  559. *
  560. * @param {object} configs
  561. * @returns {object}
  562. * @private
  563. * @method _getRmAdditionalDependencies
  564. */
  565. _getRmAdditionalDependencies: function (configs) {
  566. var ret = {};
  567. var cfg = configs['yarn-site']['yarn.resourcemanager.hostname.rm1'];
  568. if (cfg) {
  569. ret.rm1 = cfg;
  570. }
  571. return ret;
  572. },
  573. /**
  574. * Settings used to the App.MoveOSConfigInitializer setup
  575. *
  576. * @param {object} configs
  577. * @returns {object}
  578. * @private
  579. * @method _getOsInitializerSettings
  580. */
  581. _getOsInitializerSettings: function (configs) {
  582. var ret = {};
  583. var cfg = configs['oozie-env']['oozie_user'];
  584. if (cfg) {
  585. ret.oozieUser = cfg;
  586. }
  587. return ret;
  588. },
  589. /**
  590. * Get additional dependencies-data for App.MoveNameNodeConfigInitializer
  591. *
  592. * @param {object} configs
  593. * @returns {object}
  594. * @private
  595. * @method _getNnInitializerSettings
  596. */
  597. _getNnInitializerSettings: function (configs) {
  598. var ret = {};
  599. if (App.get('isHaEnabled')) {
  600. ret.namespaceId = configs['hdfs-site']['dfs.nameservices'];
  601. ret.suffix = (configs['hdfs-site']['dfs.namenode.http-address.' + ret.namespaceId + '.nn1'] === this.get('content.reassignHosts.source') + ':50070') ? 'nn1' : 'nn2';
  602. }
  603. return ret;
  604. },
  605. /**
  606. * Settings used to the App.MoveHsConfigInitializer and App.MoveHmConfigInitializer setup
  607. *
  608. * @param {object} configs
  609. * @returns {{hiveUser: string, webhcatUser: string}}
  610. * @private
  611. * @method _getHiveInitializerSettings
  612. */
  613. _getHiveInitializerSettings: function (configs) {
  614. return {
  615. hiveUser: configs['hive-env']['hive_user'],
  616. webhcatUser: configs['hive-env']['webhcat_user']
  617. };
  618. },
  619. /**
  620. * Settings used to the App.MoveRmConfigInitializer setup
  621. *
  622. * @param {object} configs
  623. * @returns {{suffix: string}}
  624. * @private
  625. * @method _getRmInitializerSettings
  626. */
  627. _getRmInitializerSettings: function (configs) {
  628. return {
  629. suffix: configs['yarn-site']['yarn.resourcemanager.hostname.rm1'] === this.get('content.reassignHosts.source') ? 'rm1': 'rm2'
  630. };
  631. },
  632. onLoadConfigs: function (data) {
  633. var componentName = this.get('content.reassign.component_name');
  634. var targetHostName = this.get('content.reassignHosts.target');
  635. var configs = {};
  636. var secureConfigs = [];
  637. data.items.forEach(function (item) {
  638. configs[item.type] = item.properties;
  639. }, this);
  640. this.setAdditionalConfigs(configs, componentName, targetHostName);
  641. this.setSecureConfigs(secureConfigs, configs, componentName);
  642. switch (componentName) {
  643. case 'NAMENODE':
  644. App.MoveNameNodeConfigInitializer.setup(this._getNnInitializerSettings(configs));
  645. configs = this.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer);
  646. App.MoveNameNodeConfigInitializer.cleanup();
  647. break;
  648. case 'RESOURCEMANAGER':
  649. App.MoveRmConfigInitializer.setup(this._getRmInitializerSettings(configs));
  650. var additionalDependencies = this._getRmAdditionalDependencies(configs);
  651. configs = this.setDynamicConfigs(configs, App.MoveRmConfigInitializer, additionalDependencies);
  652. App.MoveRmConfigInitializer.cleanup();
  653. break;
  654. case 'HIVE_METASTORE':
  655. App.MoveHmConfigInitializer.setup(this._getHiveInitializerSettings(configs));
  656. configs = this.setDynamicConfigs(configs, App.MoveHmConfigInitializer);
  657. App.MoveHmConfigInitializer.cleanup();
  658. break;
  659. case 'HIVE_SERVER':
  660. App.MoveHsConfigInitializer.setup(this._getHiveInitializerSettings(configs));
  661. configs = this.setDynamicConfigs(configs, App.MoveHsConfigInitializer);
  662. App.MoveHsConfigInitializer.cleanup();
  663. break;
  664. case 'OOZIE_SERVER':
  665. App.MoveOSConfigInitializer.setup(this._getOsInitializerSettings(configs));
  666. configs = this.setDynamicConfigs(configs, App.MoveOSConfigInitializer);
  667. App.MoveOSConfigInitializer.cleanup();
  668. }
  669. this.saveClusterStatus(secureConfigs, this.getComponentDir(configs, componentName));
  670. this.saveConfigsToServer(configs);
  671. this.saveServiceProperties(configs);
  672. },
  673. /**
  674. * Set config values according to the new cluster topology
  675. *
  676. * @param {object} configs
  677. * @param {MoveComponentConfigInitializerClass} initializer
  678. * @param {object} [additionalDependencies={}]
  679. * @returns {object}
  680. * @method setDynamicConfigs
  681. */
  682. setDynamicConfigs: function (configs, initializer, additionalDependencies) {
  683. additionalDependencies = additionalDependencies || {};
  684. var topologyDB = this._prepareTopologyDB();
  685. var dependencies = this._prepareDependencies(additionalDependencies);
  686. Em.keys(configs).forEach(function (site) {
  687. Em.keys(configs[site]).forEach(function (config) {
  688. // temporary object for initializer
  689. var cfg = {
  690. name: config,
  691. filename: site,
  692. value: configs[site][config]
  693. };
  694. configs[site][config] = initializer.initialValue(cfg, topologyDB, dependencies).value;
  695. });
  696. });
  697. return configs;
  698. },
  699. /**
  700. * make PUT call to save configs to server
  701. * @param configs
  702. */
  703. saveConfigsToServer: function (configs) {
  704. App.ajax.send({
  705. name: 'common.across.services.configurations',
  706. sender: this,
  707. data: {
  708. data: '[' + this.getServiceConfigData(configs).toString() + ']'
  709. },
  710. success: 'onSaveConfigs',
  711. error: 'onTaskError'
  712. });
  713. },
  714. /**
  715. * gather and format config data before sending to server
  716. * @param configs
  717. * @return {Array}
  718. * @method getServiceConfigData
  719. */
  720. getServiceConfigData: function (configs) {
  721. var componentName = this.get('content.reassign.component_name');
  722. var tagName = 'version' + (new Date).getTime();
  723. var configData = Object.keys(configs).map(function (_siteName) {
  724. return {
  725. type: _siteName,
  726. tag: tagName,
  727. properties: configs[_siteName],
  728. service_config_version_note: Em.I18n.t('services.reassign.step4.save.configuration.note').format(App.format.role(componentName))
  729. }
  730. });
  731. var allConfigData = [];
  732. App.Service.find().forEach(function (service) {
  733. var stackService = App.StackService.find().findProperty('serviceName', service.get('serviceName'));
  734. if (stackService) {
  735. var serviceConfigData = [];
  736. Object.keys(stackService.get('configTypesRendered')).forEach(function (type) {
  737. var serviceConfigTag = configData.findProperty('type', type);
  738. if (serviceConfigTag) {
  739. serviceConfigData.pushObject(serviceConfigTag);
  740. }
  741. }, this);
  742. allConfigData.pushObject(JSON.stringify({
  743. Clusters: {
  744. desired_config: serviceConfigData
  745. }
  746. }));
  747. }
  748. }, this);
  749. return allConfigData;
  750. },
  751. /**
  752. * Get the web address port when RM HA is enabled.
  753. * @param configs
  754. * @param webAddressKey (http vs https)
  755. * */
  756. getWebAddressPort: function (configs, webAddressKey){
  757. var result = null;
  758. var rmWebAddressValue = configs['yarn-site'][webAddressKey];
  759. if(rmWebAddressValue){
  760. var tokens = rmWebAddressValue.split(":");
  761. if(tokens.length > 1){
  762. result = tokens[1];
  763. result = result.replace(/^\s+|\s+$/g, '');
  764. }
  765. }
  766. if(result) //only return non-empty result
  767. return result;
  768. else
  769. return null;
  770. },
  771. /**
  772. * set secure configs for component
  773. * @param secureConfigs
  774. * @param configs
  775. * @param componentName
  776. * @return {Boolean}
  777. */
  778. setSecureConfigs: function (secureConfigs, configs, componentName) {
  779. var securityEnabled = App.get('isKerberosEnabled');
  780. var component = this.get('secureConfigsMap').findProperty('componentName', componentName);
  781. if (Em.isNone(component) || !securityEnabled) return false;
  782. component.configs.forEach(function (config) {
  783. secureConfigs.push({
  784. keytab: configs[config.site][config.keytab],
  785. principal: configs[config.site][config.principal]
  786. });
  787. });
  788. return true;
  789. },
  790. /**
  791. * derive component directory from configurations
  792. * @param configs
  793. * @param componentName
  794. * @return {String}
  795. */
  796. getComponentDir: function (configs, componentName) {
  797. if (componentName === 'NAMENODE') {
  798. return configs['hdfs-site']['dfs.namenode.name.dir'];
  799. } else if (componentName === 'SECONDARY_NAMENODE') {
  800. return configs['hdfs-site']['dfs.namenode.checkpoint.dir'];
  801. }
  802. return '';
  803. },
  804. /**
  805. * save cluster status to server
  806. *
  807. * @param secureConfigs
  808. * @param componentDir
  809. * @return {Boolean}
  810. */
  811. saveClusterStatus: function (secureConfigs, componentDir) {
  812. if (componentDir || secureConfigs.length) {
  813. App.router.get(this.get('content.controllerName')).saveComponentDir(componentDir);
  814. App.router.get(this.get('content.controllerName')).saveSecureConfigs(secureConfigs);
  815. App.clusterStatus.setClusterStatus({
  816. clusterName: this.get('content.cluster.name'),
  817. clusterState: this.get('clusterDeployState'),
  818. wizardControllerName: this.get('content.controllerName'),
  819. localdb: App.db.data
  820. });
  821. return true;
  822. }
  823. return false;
  824. },
  825. onSaveConfigs: function () {
  826. this.onTaskCompleted();
  827. },
  828. startZooKeeperServers: function () {
  829. var components = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER');
  830. this.updateComponent('ZOOKEEPER_SERVER', components.mapProperty('hostName'), "ZOOKEEPER", "Start");
  831. },
  832. startNameNode: function () {
  833. var components = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE');
  834. this.updateComponent('NAMENODE', components.mapProperty('hostName').without(this.get('content.reassignHosts.source')), "HDFS", "Start");
  835. },
  836. /**
  837. * make server call to start services
  838. */
  839. startRequiredServices: function () {
  840. var unrelatedServices = this.get('unrelatedServicesMap')[this.get('content.reassign.component_name')];
  841. if (unrelatedServices) {
  842. this.startServices(false, unrelatedServices);
  843. } else {
  844. this.startServices(true);
  845. }
  846. },
  847. /**
  848. * make DELETE call for each host component on host
  849. */
  850. deleteHostComponents: function () {
  851. this.set('multiTaskCounter', 0);
  852. var hostComponents = this.get('hostComponents');
  853. var hostName = this.get('content.reassignHosts.source');
  854. for (var i = 0; i < hostComponents.length; i++) {
  855. App.ajax.send({
  856. name: 'common.delete.host_component',
  857. sender: this,
  858. data: {
  859. hostName: hostName,
  860. componentName: hostComponents[i]
  861. },
  862. success: 'onComponentsTasksSuccess',
  863. error: 'onDeleteHostComponentsError'
  864. });
  865. }
  866. },
  867. onDeleteHostComponentsError: function (error) {
  868. if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.NoSuchResourceException') !== -1) {
  869. this.onComponentsTasksSuccess();
  870. } else {
  871. this.onTaskError();
  872. }
  873. },
  874. done: function () {
  875. if (!this.get('isSubmitDisabled')) {
  876. this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
  877. if (this.get('content.hasManualSteps')) {
  878. App.router.send('next');
  879. } else {
  880. App.router.send('complete');
  881. }
  882. }
  883. },
  884. /**
  885. * make server call to clean MYSQL
  886. */
  887. cleanMySqlServer: function () {
  888. var hostname = App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName');
  889. if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
  890. hostname = this.get('content.reassignHosts.target');
  891. }
  892. App.ajax.send({
  893. name: 'service.mysql.clean',
  894. sender: this,
  895. data: {
  896. host: hostname
  897. },
  898. success: 'startPolling',
  899. error: 'onTaskError'
  900. });
  901. },
  902. /**
  903. * make server call to configure MYSQL
  904. */
  905. configureMySqlServer : function () {
  906. var hostname = App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName');
  907. if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
  908. hostname = this.get('content.reassignHosts.target');
  909. }
  910. App.ajax.send({
  911. name: 'service.mysql.configure',
  912. sender: this,
  913. data: {
  914. host: hostname
  915. },
  916. success: 'startPolling',
  917. error: 'onTaskError'
  918. });
  919. },
  920. startMySqlServer: function() {
  921. App.ajax.send({
  922. name: 'common.host.host_component.update',
  923. sender: this,
  924. data: {
  925. context: "Start MySQL Server",
  926. hostName: App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName'),
  927. serviceName: "HIVE",
  928. componentName: "MYSQL_SERVER",
  929. HostRoles: {
  930. state: "STARTED"
  931. }
  932. },
  933. success: 'startPolling',
  934. error: 'onTaskError'
  935. });
  936. },
  937. restartMySqlServer: function() {
  938. var context = "Restart MySql Server";
  939. var resource_filters = {
  940. component_name: "MYSQL_SERVER",
  941. hosts: App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName'),
  942. service_name: "HIVE"
  943. };
  944. var operation_level = {
  945. level: "HOST_COMPONENT",
  946. cluster_name: this.get('content.cluster.name'),
  947. service_name: "HIVE",
  948. hostcomponent_name: "MYSQL_SERVER"
  949. };
  950. App.ajax.send({
  951. name: 'restart.hostComponents',
  952. sender: this,
  953. data: {
  954. context: context,
  955. resource_filters: [resource_filters],
  956. operation_level: operation_level
  957. },
  958. success: 'startPolling',
  959. error: 'onTaskError'
  960. });
  961. },
  962. startNewMySqlServer: function() {
  963. App.ajax.send({
  964. name: 'common.host.host_component.update',
  965. sender: this,
  966. data: {
  967. context: "Start MySQL Server",
  968. hostName: this.get('content.reassignHosts.target'),
  969. serviceName: "HIVE",
  970. componentName: "MYSQL_SERVER",
  971. HostRoles: {
  972. state: "STARTED"
  973. }
  974. },
  975. success: 'startPolling',
  976. error: 'onTaskError'
  977. });
  978. },
  979. testDBConnection: function() {
  980. this.prepareDBCheckAction();
  981. },
  982. isComponentWithDB: function() {
  983. return ['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('content.reassign.component_name'));
  984. },
  985. /** @property {Object} propertiesPattern - check pattern according to type of connection properties **/
  986. propertiesPattern: function() {
  987. return {
  988. user_name: /(username|dblogin)$/ig,
  989. user_passwd: /(dbpassword|password)$/ig,
  990. db_connection_url: /jdbc\.url|connectionurl/ig,
  991. driver_class: /ConnectionDriverName|jdbc\.driver/ig,
  992. schema_name: /db\.schema\.name/ig
  993. };
  994. }.property(),
  995. /** @property {Object} connectionProperties - service specific config values mapped for custom action request **/
  996. connectionProperties: function() {
  997. var propObj = {};
  998. for (var key in this.get('propertiesPattern')) {
  999. propObj[key] = this.getConnectionProperty(this.get('propertiesPattern')[key]);
  1000. }
  1001. return propObj;
  1002. }.property('propertiesPattern'),
  1003. getConnectionProperty: function(regexp) {
  1004. var propertyName = this.get('requiredProperties').filter(function(item) {
  1005. return regexp.test(item);
  1006. })[0];
  1007. return this.get('content.serviceProperties')[propertyName];
  1008. },
  1009. /**
  1010. * Properties that stores in local storage used for handling
  1011. * last success connection.
  1012. *
  1013. * @property {Object} preparedDBProperties
  1014. **/
  1015. preparedDBProperties: function() {
  1016. var propObj = {};
  1017. for (var key in this.get('propertiesPattern')) {
  1018. var propValue = this.getConnectionProperty(this.get('propertiesPattern')[key]);
  1019. propObj[key] = propValue;
  1020. }
  1021. return propObj;
  1022. }.property(),
  1023. /** @property {object} requiredProperties - properties that necessary for database connection **/
  1024. requiredProperties: function() {
  1025. var propertiesMap = {
  1026. OOZIE: ['oozie.db.schema.name','oozie.service.JPAService.jdbc.username','oozie.service.JPAService.jdbc.password','oozie.service.JPAService.jdbc.driver','oozie.service.JPAService.jdbc.url'],
  1027. HIVE: ['ambari.hive.db.schema.name','javax.jdo.option.ConnectionUserName','javax.jdo.option.ConnectionPassword','javax.jdo.option.ConnectionDriverName','javax.jdo.option.ConnectionURL']
  1028. };
  1029. return propertiesMap[this.get('content.reassign.service_id')];
  1030. }.property(),
  1031. dbType: function() {
  1032. var databaseTypes = /MySQL|PostgreS|Oracle|Derby|MSSQL|Anywhere/gi;
  1033. var databaseProp = this.get('content.serviceProperties')[Em.getWithDefault(this.get('dbPropertyMap'), this.get('content.reassign.component_name'), null)];
  1034. return databaseProp.match(databaseTypes)[0];
  1035. }.property(),
  1036. prepareDBCheckAction: function() {
  1037. var params = this.get('preparedDBProperties');
  1038. var ambariProperties = App.router.get('clusterController.ambariProperties');
  1039. params['db_name'] = this.get('dbType');
  1040. params['jdk_location'] = ambariProperties['jdk_location'];
  1041. params['jdk_name'] = ambariProperties['jdk.name'];
  1042. params['java_home'] = ambariProperties['java.home'];
  1043. params['threshold'] = 60;
  1044. params['ambari_server_host'] = location.hostname;
  1045. params['check_execute_list'] = "db_connection_check";
  1046. App.ajax.send({
  1047. name: 'cluster.custom_action.create',
  1048. sender: this,
  1049. data: {
  1050. requestInfo: {
  1051. "context": "Check host",
  1052. "action": "check_host",
  1053. "parameters": params
  1054. },
  1055. filteredHosts: [this.get('content.reassignHosts.target')]
  1056. },
  1057. success: 'onCreateActionSuccess',
  1058. error: 'onTaskError'
  1059. });
  1060. },
  1061. onCreateActionSuccess: function(data) {
  1062. this.set('checkDBRequestId', data.Requests.id);
  1063. App.ajax.send({
  1064. name: 'custom_action.request',
  1065. sender: this,
  1066. data: {
  1067. requestId: this.get('checkDBRequestId')
  1068. },
  1069. success: 'setCheckDBTaskId'
  1070. });
  1071. },
  1072. setCheckDBTaskId: function(data) {
  1073. this.set('checkDBTaskId', data.items[0].Tasks.id);
  1074. this.startDBCheckPolling();
  1075. },
  1076. startDBCheckPolling: function() {
  1077. this.getDBConnTaskInfo();
  1078. },
  1079. getDBConnTaskInfo: function() {
  1080. this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
  1081. this.get('tasks').findProperty('id', this.get('currentTaskId')).set('progress', 100);
  1082. this.set('logs', []);
  1083. App.ajax.send({
  1084. name: 'custom_action.request',
  1085. sender: this,
  1086. data: {
  1087. requestId: this.get('checkDBRequestId'),
  1088. taskId: this.get('checkDBTaskId')
  1089. },
  1090. success: 'getDBConnTaskInfoSuccess'
  1091. });
  1092. },
  1093. getDBConnTaskInfoSuccess: function(data) {
  1094. var task = data.Tasks;
  1095. if (task.status === 'COMPLETED') {
  1096. var structuredOut = task.structured_out.db_connection_check;
  1097. if (structuredOut.exit_code != 0) {
  1098. this.showConnectionErrorPopup(structuredOut.message);
  1099. this.onTaskError();
  1100. } else {
  1101. this.onTaskCompleted();
  1102. }
  1103. }
  1104. if (task.status === 'FAILED') {
  1105. this.onTaskError();
  1106. }
  1107. if (/PENDING|QUEUED|IN_PROGRESS/.test(task.status)) {
  1108. Em.run.later(this, function() {
  1109. this.startDBCheckPolling();
  1110. }, 3000);
  1111. }
  1112. },
  1113. showConnectionErrorPopup: function(error) {
  1114. var popup = App.showAlertPopup('Database Connection Error');
  1115. popup.set('body', error);
  1116. },
  1117. testDBRetryTooltip: function() {
  1118. var db_host = this.get('content.serviceProperties.database_hostname');
  1119. var db_type = this.get('dbType');
  1120. var db_props = this.get('preparedDBProperties');
  1121. return Em.I18n.t('services.reassign.step4.tasks.testDBConnection.tooltip').format(
  1122. db_host, db_type, db_props['schema_name'], db_props['user_name'],
  1123. db_props['user_passwd'], db_props['driver_class'], db_props['db_connection_url']
  1124. );
  1125. }.property('dbProperties'),
  1126. saveServiceProperties: function(configs) {
  1127. App.router.get(this.get('content.controllerName')).saveServiceProperties(configs);
  1128. }
  1129. });