step4_controller.js 39 KB

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