step4_controller.js 39 KB

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