step4_controller.js 39 KB

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