details.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  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. var batchUtils = require('utils/batch_scheduled_requests');
  20. App.MainHostDetailsController = Em.Controller.extend({
  21. name: 'mainHostDetailsController',
  22. content: null,
  23. isFromHosts: false,
  24. /**
  25. * path to page visited before
  26. */
  27. referer: '',
  28. /**
  29. * open dashboard page
  30. */
  31. routeHome: function () {
  32. App.router.transitionTo('main.dashboard');
  33. },
  34. /**
  35. * open summary page of the selected service
  36. * @param event
  37. */
  38. routeToService: function(event){
  39. var service = event.context;
  40. App.router.transitionTo('main.services.service.summary',service);
  41. },
  42. /**
  43. * Send specific command to server
  44. * @param url
  45. * @param _method
  46. * @param postData
  47. * @param callback
  48. */
  49. sendCommandToServer : function(url, postData, _method, callback){
  50. var url = (App.testMode) ?
  51. '/data/wizard/deploy/poll_1.json' : //content is the same as ours
  52. App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  53. var method = App.testMode ? 'GET' : _method;
  54. $.ajax({
  55. type: method,
  56. url: url,
  57. data: JSON.stringify(postData),
  58. dataType: 'json',
  59. timeout: App.timeout,
  60. success: function(data){
  61. if(data && data.Requests){
  62. callback(data.Requests.id);
  63. } else{
  64. callback(null);
  65. console.log('cannot get request id from ', data);
  66. }
  67. },
  68. error: function (request, ajaxOptions, error) {
  69. //do something
  70. console.log('error on change component host status');
  71. App.ajax.defaultErrorHandler(request, url, method);
  72. },
  73. statusCode: require('data/statusCodes')
  74. });
  75. },
  76. /**
  77. * send command to server to start selected host component
  78. * @param event
  79. */
  80. startComponent: function (event) {
  81. var self = this;
  82. App.showConfirmationPopup(function() {
  83. var component = event.context;
  84. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  85. self.sendStartComponentCommand(component, context);
  86. });
  87. },
  88. /**
  89. * PUTs a command to server to start a component. If no
  90. * specific component is provided, all components are started.
  91. * @param component When <code>null</code> all startable components are started.
  92. * @param context Context under which this command is beign sent.
  93. */
  94. sendStartComponentCommand: function(component, context) {
  95. var url = component !== null ?
  96. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  97. '/hosts/' + this.get('content.hostName') + '/host_components?HostRoles/passive_state=ACTIVE';
  98. var dataToSend = {
  99. RequestInfo : {
  100. "context" : context
  101. },
  102. Body:{
  103. HostRoles:{
  104. state: 'STARTED'
  105. }
  106. }
  107. };
  108. if (component === null) {
  109. var allComponents = this.get('content.hostComponents');
  110. var startable = [];
  111. allComponents.forEach(function (c) {
  112. if (c.get('passiveState') == 'ACTIVE') {
  113. if (c.get('isMaster') || c.get('isSlave')) {
  114. startable.push(c.get('componentName'));
  115. }
  116. }
  117. });
  118. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + startable.join(',') + ")";
  119. }
  120. this.sendCommandToServer(url, dataToSend, 'PUT',
  121. function(requestId){
  122. if(!requestId){
  123. return;
  124. }
  125. console.log('Send request for STARTING successfully');
  126. if (App.testMode) {
  127. if(component === null){
  128. var allComponents = this.get('content.hostComponents');
  129. allComponents.forEach(function(component){
  130. component.set('workStatus', App.HostComponentStatus.stopping);
  131. setTimeout(function(){
  132. component.set('workStatus', App.HostComponentStatus.stopped);
  133. },App.testModeDelayForActions);
  134. });
  135. } else {
  136. component.set('workStatus', App.HostComponentStatus.starting);
  137. setTimeout(function(){
  138. component.set('workStatus', App.HostComponentStatus.started);
  139. },App.testModeDelayForActions);
  140. }
  141. } else {
  142. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  143. }
  144. // load data (if we need to show this background operations popup) from persist
  145. App.router.get('applicationController').dataLoading().done(function (initValue) {
  146. if (initValue) {
  147. App.router.get('backgroundOperationsController').showPopup();
  148. }
  149. });
  150. });
  151. },
  152. /**
  153. * send command to server to delete selected host component
  154. *
  155. */
  156. deleteComponent: function (event) {
  157. var self = this;
  158. var component = event.context;
  159. var componentName = component.get('componentName');
  160. var displayName = component.get('displayName');
  161. var isLastComponent = (App.HostComponent.find().filterProperty('componentName', componentName).get('length') === 1);
  162. App.ModalPopup.show({
  163. header: Em.I18n.t('popup.confirmation.commonHeader'),
  164. bodyClass: Ember.View.extend({
  165. templateName: require('templates/main/host/details/deleteComponentPopup')
  166. }),
  167. enablePrimary: false,
  168. lastComponent: function() {
  169. if (isLastComponent) {
  170. this.set('enablePrimary',false);
  171. return true;
  172. } else {
  173. this.set('enablePrimary',true);
  174. return false;
  175. }
  176. }.property(),
  177. lastComponentError: Em.View.extend({
  178. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  179. }),
  180. deleteComponentMsg: function() {
  181. return Em.I18n.t('hosts.host.deleteComponent.popup.msg').format(displayName);
  182. }.property(),
  183. onPrimary: function () {
  184. if (!this.get('enablePrimary')) return;
  185. self._doDeleteHostComponent(component);
  186. this.hide();
  187. }
  188. });
  189. },
  190. /**
  191. * Deletes the given host component, or all host components.
  192. *
  193. * @param component When <code>null</code> all host components are deleted.
  194. * @return <code>null</code> when components get deleted.
  195. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  196. * when components failed to get deleted.
  197. */
  198. _doDeleteHostComponent: function(component) {
  199. var url = component !== null ?
  200. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  201. '/hosts/' + this.get('content.hostName') + '/host_components';
  202. url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  203. var deleted = null;
  204. $.ajax({
  205. type: 'DELETE',
  206. url: url,
  207. timeout: App.timeout,
  208. async: false,
  209. success: function (data) {
  210. deleted = null;
  211. },
  212. error: function (xhr, textStatus, errorThrown) {
  213. console.log('Error deleting host component');
  214. console.log(textStatus);
  215. console.log(errorThrown);
  216. deleted = {xhr: xhr, url: url, method: 'DELETE'};
  217. },
  218. statusCode: require('data/statusCodes')
  219. });
  220. return deleted;
  221. },
  222. /**
  223. * send command to server to upgrade selected host component
  224. * @param event
  225. */
  226. upgradeComponent: function (event) {
  227. var self = this;
  228. var component = event.context;
  229. App.showConfirmationPopup(function() {
  230. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(),{
  231. RequestInfo : {
  232. "context" : Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  233. },
  234. Body:{
  235. HostRoles:{
  236. stack_id: 'HDP-1.2.2',
  237. state: 'INSTALLED'
  238. }
  239. }
  240. }, 'PUT',
  241. function(requestId){
  242. if(!requestId){
  243. return;
  244. }
  245. console.log('Send request for UPGRADE successfully');
  246. if (App.testMode) {
  247. component.set('workStatus', App.HostComponentStatus.starting);
  248. setTimeout(function(){
  249. component.set('workStatus', App.HostComponentStatus.started);
  250. },App.testModeDelayForActions);
  251. } else {
  252. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  253. }
  254. // load data (if we need to show this background operations popup) from persist
  255. App.router.get('applicationController').dataLoading().done(function (initValue) {
  256. if (initValue) {
  257. App.router.get('backgroundOperationsController').showPopup();
  258. }
  259. });
  260. });
  261. });
  262. },
  263. /**
  264. * send command to server to stop selected host component
  265. * @param event
  266. */
  267. stopComponent: function (event) {
  268. var self = this;
  269. App.showConfirmationPopup(function() {
  270. var component = event.context;
  271. var context = Em.I18n.t('requestInfo.stopHostComponent')+ " " + component.get('displayName');
  272. self.sendStopComponentCommand(component, context);
  273. });
  274. },
  275. /**
  276. * PUTs a command to server to stop a component. If no
  277. * specific component is provided, all components are stopped.
  278. * @param component When <code>null</code> all components are stopped.
  279. * @param context Context under which this command is beign sent.
  280. */
  281. sendStopComponentCommand: function(component, context){
  282. var url = component !== null ?
  283. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  284. '/hosts/' + this.get('content.hostName') + '/host_components?HostRoles/passive_state=ACTIVE';
  285. var dataToSend = {
  286. RequestInfo : {
  287. "context" : context
  288. },
  289. Body:{
  290. HostRoles:{
  291. state: 'INSTALLED'
  292. }
  293. }
  294. };
  295. if (component === null) {
  296. var allComponents = this.get('content.hostComponents');
  297. var startable = [];
  298. allComponents.forEach(function (c) {
  299. if (c.get('passiveState') == 'ACTIVE') {
  300. if (c.get('isMaster') || c.get('isSlave')) {
  301. startable.push(c.get('componentName'));
  302. }
  303. }
  304. });
  305. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + startable.join(',') + ")";
  306. }
  307. this.sendCommandToServer( url, dataToSend, 'PUT',
  308. function(requestId){
  309. if(!requestId){
  310. return;
  311. }
  312. console.log('Send request for STOPPING successfully');
  313. if (App.testMode) {
  314. if(component === null){
  315. var allComponents = this.get('content.hostComponents');
  316. allComponents.forEach(function(component){
  317. component.set('workStatus', App.HostComponentStatus.stopping);
  318. setTimeout(function(){
  319. component.set('workStatus', App.HostComponentStatus.stopped);
  320. },App.testModeDelayForActions);
  321. });
  322. } else {
  323. component.set('workStatus', App.HostComponentStatus.stopping);
  324. setTimeout(function(){
  325. component.set('workStatus', App.HostComponentStatus.stopped);
  326. },App.testModeDelayForActions);
  327. }
  328. } else {
  329. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  330. }
  331. // load data (if we need to show this background operations popup) from persist
  332. App.router.get('applicationController').dataLoading().done(function (initValue) {
  333. if (initValue) {
  334. App.router.get('backgroundOperationsController').showPopup();
  335. }
  336. });
  337. });
  338. },
  339. restartComponent: function(event) {
  340. var component = event.context;
  341. App.showConfirmationPopup(function(){
  342. batchUtils.restartHostComponents([component]);
  343. });
  344. },
  345. /**
  346. * send command to server to install selected host component
  347. * @param event
  348. */
  349. addComponent: function (event) {
  350. var self = this;
  351. var component = event.context;
  352. var componentName = component.get('componentName').toUpperCase().toString();
  353. var subComponentNames = component.get('subComponentNames');
  354. var displayName = component.get('displayName');
  355. var securityEnabled = App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus();
  356. if (componentName === 'ZOOKEEPER_SERVER') {
  357. App.showConfirmationPopup(function() {
  358. self.primary(component);
  359. }, Em.I18n.t('hosts.host.addComponent.addZooKeeper'));
  360. }
  361. else {
  362. if (securityEnabled) {
  363. App.showConfirmationPopup(function() {
  364. self.primary(component);
  365. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName,self.get('content.hostName')));
  366. }
  367. else {
  368. var dn = displayName;
  369. if (subComponentNames !== null && subComponentNames.length > 0) {
  370. var dns = [];
  371. subComponentNames.forEach(function(scn){
  372. dns.push(App.format.role(scn));
  373. });
  374. dn += " ("+dns.join(", ")+")";
  375. }
  376. App.ModalPopup.show({
  377. primary: Em.I18n.t('yes'),
  378. secondary: Em.I18n.t('no'),
  379. header: Em.I18n.t('popup.confirmation.commonHeader'),
  380. addComponentMsg: function() {
  381. return Em.I18n.t('hosts.host.addComponent.msg').format(dn);
  382. }.property(),
  383. bodyClass: Ember.View.extend({
  384. templateName: require('templates/main/host/details/addComponentPopup')
  385. }),
  386. onPrimary: function () {
  387. this.hide();
  388. if (component.get('componentName') === 'CLIENTS') {
  389. // Clients component has many sub-components which
  390. // need to be installed.
  391. var scs = component.get('subComponentNames');
  392. scs.forEach(function (sc, index) {
  393. var c = Em.Object.create({
  394. displayName: App.format.role(sc),
  395. componentName: sc
  396. });
  397. self.primary(c, scs.length - index === 1);
  398. });
  399. } else {
  400. self.primary(component, true);
  401. }
  402. }
  403. });
  404. }
  405. }
  406. },
  407. primary: function(component, showPopup) {
  408. var self = this;
  409. var componentName = component.get('componentName').toUpperCase().toString();
  410. var displayName = component.get('displayName');
  411. self.sendCommandToServer('/hosts?Hosts/host_name=' + self.get('content.hostName'), {
  412. RequestInfo: {
  413. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  414. },
  415. Body: {
  416. host_components: [
  417. {
  418. HostRoles: {
  419. component_name: componentName
  420. }
  421. }
  422. ]
  423. }
  424. },
  425. 'POST',
  426. function (requestId) {
  427. console.log('Send request for ADDING NEW COMPONENT successfully');
  428. self.sendCommandToServer('/host_components?HostRoles/host_name=' + self.get('content.hostName') + '\&HostRoles/component_name=' + componentName + '\&HostRoles/state=INIT', {
  429. RequestInfo: {
  430. "context": Em.I18n.t('requestInfo.installNewHostComponent') + " " + displayName
  431. },
  432. Body: {
  433. HostRoles: {
  434. state: 'INSTALLED'
  435. }
  436. }
  437. },
  438. 'PUT',
  439. function (requestId) {
  440. if (!requestId) {
  441. return;
  442. }
  443. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  444. if (App.testMode) {
  445. component.set('workStatus', App.HostComponentStatus.installing);
  446. setTimeout(function () {
  447. component.set('workStatus', App.HostComponentStatus.stopped);
  448. }, App.testModeDelayForActions);
  449. } else {
  450. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  451. }
  452. // load data (if we need to show this background operations popup) from persist
  453. App.router.get('applicationController').dataLoading().done(function (initValue) {
  454. if (initValue) {
  455. App.router.get('backgroundOperationsController').showPopup();
  456. }
  457. if (componentName === 'ZOOKEEPER_SERVER') {
  458. self.set('zkRequestId', requestId);
  459. self.addObserver('App.router.backgroundOperationsController.serviceTimestamp', self, self.checkZkConfigs);
  460. self.checkZkConfigs();
  461. }
  462. });
  463. });
  464. });
  465. },
  466. /**
  467. * Load tags
  468. */
  469. checkZkConfigs: function() {
  470. var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId'));
  471. if (!bg) return;
  472. if (!bg.get('isRunning')) {
  473. this.loadConfigs();
  474. }
  475. },
  476. loadConfigs: function() {
  477. this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs);
  478. App.ajax.send({
  479. name: 'config.tags',
  480. sender: this,
  481. success: 'loadConfigsSuccessCallback'
  482. });
  483. },
  484. /**
  485. * Load needed configs
  486. * @param data
  487. */
  488. loadConfigsSuccessCallback: function(data) {
  489. var urlParams = [];
  490. urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
  491. if (App.Service.find().someProperty('serviceName', 'HBASE')) {
  492. urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
  493. }
  494. if (App.Service.find().someProperty('serviceName', 'HIVE')) {
  495. urlParams.push('(type=webhcat-site&tag=' + data.Clusters.desired_configs['webhcat-site'].tag + ')');
  496. }
  497. App.ajax.send({
  498. name: 'reassign.load_configs',
  499. sender: this,
  500. data: {
  501. urlParams: urlParams.join('|')
  502. },
  503. success: 'setNewZkConfigs'
  504. });
  505. },
  506. /**
  507. * Set new values for some configs (based on available ZooKeeper Servers)
  508. * @param data
  509. */
  510. setNewZkConfigs: function(data) {
  511. var configs = [];
  512. data.items.forEach(function (item) {
  513. configs[item.type] = item.properties;
  514. }, this);
  515. var zks = this.getZkServerHosts();
  516. var zks_with_port = '';
  517. zks.forEach(function(zk) {
  518. zks_with_port += zk + ':2181,';
  519. });
  520. zks_with_port = zks_with_port.slice(0,-1);
  521. if (App.get('isHaEnabled')) {
  522. configs['core-site']['ha.zookeeper.quorum'] = zks_with_port;
  523. }
  524. if (configs['hbase-site']) {
  525. configs['hbase-site']['hbase.zookeeper.quorum'] = zks.join(',');
  526. }
  527. if (configs['webhcat-site']) {
  528. configs['webhcat-site']['templeton.zookeeper.hosts'] = zks_with_port;
  529. }
  530. for (var site in configs) {
  531. if (!configs.hasOwnProperty(site)) continue;
  532. App.ajax.send({
  533. name: 'reassign.save_configs',
  534. sender: this,
  535. data: {
  536. siteName: site,
  537. properties: configs[site]
  538. }
  539. });
  540. }
  541. },
  542. /**
  543. * Is deleteHost action id fired
  544. */
  545. fromDeleteHost: false,
  546. getZkServerHosts: function() {
  547. var zks = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('host.hostName');
  548. if (this.get('fromDeleteHost')) {
  549. this.set('fromDeleteHost', false);
  550. return zks.without(this.get('content.hostName'));
  551. }
  552. return zks;
  553. },
  554. /**
  555. * send command to server to install selected host component
  556. * @param event
  557. * @param context
  558. */
  559. installComponent: function (event, context) {
  560. var self = this;
  561. var component = event.context;
  562. var componentName = component.get('componentName').toUpperCase().toString();
  563. var displayName = component.get('displayName');
  564. App.ModalPopup.show({
  565. primary: Em.I18n.t('yes'),
  566. secondary: Em.I18n.t('no'),
  567. header: Em.I18n.t('popup.confirmation.commonHeader'),
  568. installComponentMessage: function(){
  569. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  570. }.property(),
  571. bodyClass: Ember.View.extend({
  572. templateName: require('templates/main/host/details/installComponentPopup')
  573. }),
  574. onPrimary: function () {
  575. this.hide();
  576. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(), {
  577. RequestInfo: {
  578. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  579. },
  580. Body: {
  581. HostRoles: {
  582. state: 'INSTALLED'
  583. }
  584. }
  585. },
  586. 'PUT',
  587. function (requestId) {
  588. if (!requestId) {
  589. return;
  590. }
  591. console.log('Send request for REINSTALL COMPONENT successfully');
  592. if (App.testMode) {
  593. component.set('workStatus', App.HostComponentStatus.installing);
  594. setTimeout(function () {
  595. component.set('workStatus', App.HostComponentStatus.stopped);
  596. }, App.testModeDelayForActions);
  597. } else {
  598. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  599. }
  600. // load data (if we need to show this background operations popup) from persist
  601. App.router.get('applicationController').dataLoading().done(function (initValue) {
  602. if (initValue) {
  603. App.router.get('backgroundOperationsController').showPopup();
  604. }
  605. });
  606. });
  607. }
  608. });
  609. },
  610. /**
  611. * send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
  612. * @param event
  613. */
  614. decommission: function(event){
  615. var self = this;
  616. App.showConfirmationPopup(function(){
  617. var component = event.context;
  618. var svcName = component.get('service.serviceName');
  619. var hostName = self.get('content.hostName');
  620. // HDFS service, decommission DataNode
  621. if (svcName === "HDFS") {
  622. self.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
  623. }
  624. // YARN service, decommission NodeManager
  625. if (svcName === "YARN") {
  626. self.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
  627. }
  628. // MAPREDUCE service, decommission TaskTracker
  629. if (svcName === "MAPREDUCE") {
  630. self.doDecommission(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  631. }
  632. // HBASE service, decommission RegionServer
  633. if (svcName === "HBASE") {
  634. self.doDecommissionRegionServer(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
  635. }
  636. // load data (if we need to show this background operations popup) from persist
  637. App.router.get('applicationController').dataLoading().done(function (initValue) {
  638. if (initValue) {
  639. App.router.get('backgroundOperationsController').showPopup();
  640. }
  641. });
  642. });
  643. },
  644. /**
  645. * send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
  646. * @param event
  647. */
  648. recommission: function(event){
  649. var self = this;
  650. App.showConfirmationPopup(function(){
  651. var component = event.context;
  652. var svcName = component.get('service.serviceName');
  653. var hostName = self.get('content.hostName');
  654. var start_context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  655. // HDFS service, Recommission datanode
  656. if (svcName === "HDFS") {
  657. self.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE", start_context);
  658. }
  659. // YARN service, Recommission nodeManager
  660. if (svcName === "YARN") {
  661. self.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER", start_context);
  662. }
  663. // MAPREDUCE service, Recommission taskTracker
  664. if (svcName === "MAPREDUCE") {
  665. self.doRecommissionAndRestart(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
  666. }
  667. // HBASE service, Recommission RegionServer
  668. if (svcName === "HBASE") {
  669. self.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER", start_context);
  670. }
  671. // load data (if we need to show this background operations popup) from persist
  672. App.router.get('applicationController').dataLoading().done(function (initValue) {
  673. if (initValue) {
  674. App.router.get('backgroundOperationsController').showPopup();
  675. }
  676. });
  677. });
  678. },
  679. /**
  680. * Performs Decommission (for DN, TT and NM)
  681. */
  682. doDecommission: function(hostName, serviceName, componentName, slaveType){
  683. var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
  684. var context = Em.I18n.t(contextNameString);
  685. App.ajax.send({
  686. name: 'host.host_component.decommission_slave',
  687. sender: this,
  688. data: {
  689. context: context,
  690. command: 'DECOMMISSION',
  691. hostName: hostName,
  692. serviceName: serviceName ,
  693. componentName: componentName,
  694. slaveType: slaveType
  695. },
  696. success: 'decommissionSuccessCallback',
  697. error: 'decommissionErrorCallback'
  698. });
  699. },
  700. /**
  701. * Performs Decommission (for RegionServer)
  702. */
  703. doDecommissionRegionServer: function(hostName, serviceName, componentName, slaveType){
  704. App.ajax.send({
  705. name: 'host.host_component.recommission_and_restart',
  706. sender: this,
  707. data: {
  708. intervalTimeSeconds: 1,
  709. tolerateSize : 0,
  710. batches:[
  711. {
  712. "order_id" : 1,
  713. "type" : "POST",
  714. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  715. "RequestBodyInfo" : {
  716. "RequestInfo" : {
  717. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
  718. "command" : "DECOMMISSION",
  719. "service_name" : serviceName,
  720. "component_name" : componentName,
  721. "parameters" : {
  722. "slave_type": slaveType,
  723. "excluded_hosts": hostName
  724. }
  725. }
  726. }
  727. },
  728. {
  729. "order_id" : 2,
  730. "type" : "PUT",
  731. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components/" + slaveType.toUpperCase(),
  732. "RequestBodyInfo" : {
  733. "RequestInfo" : {
  734. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch2')
  735. },
  736. "Body": {
  737. "HostRoles": {
  738. "state": 'INSTALLED'
  739. }
  740. }
  741. }
  742. },
  743. {
  744. "order_id" : 3,
  745. "type" : "POST",
  746. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  747. "RequestBodyInfo" : {
  748. "RequestInfo" : {
  749. "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
  750. "command" : "DECOMMISSION",
  751. "service_name" : serviceName,
  752. "component_name" : componentName,
  753. "parameters" : {
  754. "slave_type": slaveType,
  755. "excluded_hosts": hostName,
  756. "mark_draining_only": "true"
  757. }
  758. }
  759. }
  760. }
  761. ]
  762. },
  763. success: 'decommissionSuccessCallback',
  764. error: 'decommissionErrorCallback'
  765. });
  766. },
  767. decommissionErrorCallback: function (request, ajaxOptions, error) {
  768. console.log('ERROR: '+ error);
  769. },
  770. /**
  771. * Success ajax response for Recommission/Decommission slaves
  772. * @param data
  773. * @param ajaxOptions
  774. */
  775. decommissionSuccessCallback: function(data, ajaxOptions) {
  776. if(data && (data.Requests || data.resources[0].RequestSchedule) ) {
  777. if (!App.testMode) {
  778. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  779. }
  780. // load data (if we need to show this background operations popup) from persist
  781. App.router.get('applicationController').dataLoading().done(function (initValue) {
  782. if (initValue) {
  783. App.router.get('backgroundOperationsController').showPopup();
  784. }
  785. });
  786. }
  787. else {
  788. console.log('cannot get request id from ', data);
  789. }
  790. },
  791. doRecommissionAndStart: function(hostName, serviceName, componentName, slaveType, startContext){
  792. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  793. var context_1 = Em.I18n.t(contextNameString_1);
  794. App.ajax.send({
  795. name: 'host.host_component.recommission_and_restart',
  796. sender: this,
  797. data: {
  798. intervalTimeSeconds: 1,
  799. tolerateSize : 1,
  800. batches:[
  801. {
  802. "order_id" : 1,
  803. "type" : "POST",
  804. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  805. "RequestBodyInfo" : {
  806. "RequestInfo" : {
  807. "context" : context_1,
  808. "command" : "DECOMMISSION",
  809. "service_name" : serviceName,
  810. "component_name" : componentName,
  811. "parameters" : {
  812. "slave_type": slaveType,
  813. "included_hosts": hostName
  814. }
  815. }
  816. }
  817. },
  818. {
  819. "order_id" : 2,
  820. "type" : "PUT",
  821. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components/" + slaveType.toUpperCase(),
  822. "RequestBodyInfo" : {
  823. "RequestInfo" : {
  824. "context" : startContext
  825. },
  826. "Body": {
  827. "HostRoles": {
  828. "state": 'STARTED'
  829. }
  830. }
  831. }
  832. }
  833. ]
  834. },
  835. success: 'decommissionSuccessCallback',
  836. error: 'decommissionErrorCallback'
  837. });
  838. },
  839. doRecommissionAndRestart: function(hostName, serviceName, componentName, slaveType){
  840. var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
  841. var context_1 = Em.I18n.t(contextNameString_1);
  842. var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
  843. var context_2 = Em.I18n.t(contextNameString_2);
  844. App.ajax.send({
  845. name: 'host.host_component.recommission_and_restart',
  846. sender: this,
  847. data: {
  848. intervalTimeSeconds: 1,
  849. tolerateSize : 1,
  850. batches:[
  851. {
  852. "order_id" : 1,
  853. "type" : "POST",
  854. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  855. "RequestBodyInfo" : {
  856. "RequestInfo" : {
  857. "context" : context_1,
  858. "command" : "DECOMMISSION",
  859. "service_name" : serviceName,
  860. "component_name" : componentName,
  861. "parameters" : {
  862. "slave_type": slaveType,
  863. "included_hosts": hostName
  864. }
  865. }
  866. }
  867. },
  868. {
  869. "order_id" : 2,
  870. "type" : "POST",
  871. "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
  872. "RequestBodyInfo" : {
  873. "RequestInfo" : {
  874. "context" : context_2,
  875. "command" : "RESTART",
  876. "service_name" : serviceName,
  877. "component_name" : slaveType,
  878. "hosts" : hostName
  879. }
  880. }
  881. }
  882. ]
  883. },
  884. success: 'decommissionSuccessCallback',
  885. error: 'decommissionErrorCallback'
  886. });
  887. },
  888. doAction: function(option) {
  889. switch (option.context.action) {
  890. case "deleteHost":
  891. this.validateAndDeleteHost();
  892. break;
  893. case "startAllComponents":
  894. this.doStartAllComponents();
  895. break;
  896. case "stopAllComponents":
  897. this.doStopAllComponents();
  898. break;
  899. case "restartAllComponents":
  900. this.doRestartAllComponents();
  901. break;
  902. case "onOffPassiveModeForHost":
  903. this.onOffPassiveModeForHost(option.context);
  904. break;
  905. default:
  906. break;
  907. }
  908. },
  909. onOffPassiveModeForHost: function(context) {
  910. var state = context.active ? 'PASSIVE' : 'ACTIVE';
  911. var self = this;
  912. App.showConfirmationPopup(function() {
  913. self.hostPassiveModeRequest(state, context.label)
  914. },
  915. Em.I18n.t('hosts.passiveMode.popup').format(context.active ? 'On' : 'Off',this.get('content.hostName'))
  916. );
  917. },
  918. hostPassiveModeRequest: function(state,message) {
  919. App.ajax.send({
  920. name: 'bulk_request.hosts.passive_state',
  921. sender: this,
  922. data: {
  923. hostNames: this.get('content.hostName'),
  924. passive_state: state,
  925. requestInfo: message
  926. },
  927. success: 'updateHost'
  928. });
  929. },
  930. updateHost: function(data, opt, params) {
  931. this.set('content.passiveState', params.passive_state);
  932. App.router.get('clusterController').loadUpdatedStatus(function(){});
  933. },
  934. doStartAllComponents: function() {
  935. var self = this;
  936. var components = this.get('content.hostComponents');
  937. var componentsLength = components == null ? 0 : components.get('length');
  938. if (componentsLength > 0) {
  939. App.showConfirmationPopup(function() {
  940. self.sendStartComponentCommand(null,
  941. Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  942. });
  943. }
  944. },
  945. doStopAllComponents: function() {
  946. var self = this;
  947. var components = this.get('content.hostComponents');
  948. var componentsLength = components == null ? 0 : components.get('length');
  949. if (componentsLength > 0) {
  950. App.showConfirmationPopup(function() {
  951. self.sendStopComponentCommand(null,
  952. Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  953. });
  954. }
  955. },
  956. doRestartAllComponents: function() {
  957. var components = this.get('content.hostComponents').filterProperty('passiveState','ACTIVE');
  958. var componentsLength = components == null ? 0 : components.get('length');
  959. if (componentsLength > 0) {
  960. App.showConfirmationPopup(function() {
  961. batchUtils.restartHostComponents(components);
  962. });
  963. }
  964. },
  965. /**
  966. * Deletion of hosts not supported for this version
  967. */
  968. validateAndDeleteHost: function () {
  969. if (!App.supports.deleteHost) {
  970. return;
  971. }
  972. var stoppedStates = [App.HostComponentStatus.stopped,
  973. App.HostComponentStatus.install_failed,
  974. App.HostComponentStatus.upgrade_failed,
  975. App.HostComponentStatus.unknown];
  976. var masterComponents = [];
  977. var runningComponents = [];
  978. var unknownComponents = [];
  979. var nonDeletableComponents = [];
  980. var lastComponents = [];
  981. var componentsOnHost = this.get('content.hostComponents');
  982. var allComponents = App.HostComponent.find();
  983. var zkServerInstalled = false;
  984. if (componentsOnHost && componentsOnHost.get('length') > 0) {
  985. componentsOnHost.forEach(function (cInstance) {
  986. if (cInstance.get('componentName') === 'ZOOKEEPER_SERVER') {
  987. zkServerInstalled = true;
  988. }
  989. if (allComponents.filterProperty('componentName', cInstance.get('componentName')).get('length') === 1) {
  990. lastComponents.push(cInstance.get('displayName'));
  991. }
  992. var workStatus = cInstance.get('workStatus');
  993. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  994. masterComponents.push(cInstance.get('displayName'));
  995. }
  996. if (stoppedStates.indexOf(workStatus) < 0) {
  997. runningComponents.push(cInstance.get('displayName'));
  998. }
  999. if (!cInstance.get('isDeletable')) {
  1000. nonDeletableComponents.push(cInstance.get('displayName'));
  1001. }
  1002. if (workStatus === App.HostComponentStatus.unknown) {
  1003. unknownComponents.push(cInstance.get('displayName'));
  1004. }
  1005. });
  1006. }
  1007. if (masterComponents.length > 0) {
  1008. this.raiseDeleteComponentsError(masterComponents, 'masterList');
  1009. return;
  1010. } else if (nonDeletableComponents.length > 0) {
  1011. this.raiseDeleteComponentsError(nonDeletableComponents, 'nonDeletableList');
  1012. return;
  1013. } else if (runningComponents.length > 0) {
  1014. this.raiseDeleteComponentsError(runningComponents, 'runningList');
  1015. return;
  1016. }
  1017. if (zkServerInstalled) {
  1018. var self = this;
  1019. App.showConfirmationPopup(function() {
  1020. self._doDeleteHost(unknownComponents, lastComponents);
  1021. }, Em.I18n.t('hosts.host.addComponent.deleteHostWithZooKeeper'));
  1022. }
  1023. else {
  1024. this._doDeleteHost(unknownComponents, lastComponents);
  1025. }
  1026. },
  1027. raiseDeleteComponentsError: function (components, type) {
  1028. App.ModalPopup.show({
  1029. header: Em.I18n.t('hosts.cant.do.popup.title'),
  1030. type: type,
  1031. showBodyEnd: function() {
  1032. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  1033. }.property(),
  1034. components: components,
  1035. componentsStr: function() {
  1036. return this.get('components').join(", ");
  1037. }.property(),
  1038. componentsBody: function() {
  1039. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body').format(this.get('components').length);
  1040. }.property(),
  1041. componentsBodyEnd: function() {
  1042. if (this.get('showBodyEnd')) {
  1043. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body.end');
  1044. }
  1045. return '';
  1046. }.property(),
  1047. bodyClass: Em.View.extend({
  1048. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  1049. }),
  1050. secondary: null
  1051. })
  1052. },
  1053. /**
  1054. * show confirmation popup to delete host
  1055. */
  1056. _doDeleteHost: function(unknownComponents,lastComponents) {
  1057. var self = this;
  1058. App.ModalPopup.show({
  1059. header: Em.I18n.t('hosts.delete.popup.title'),
  1060. deletePopupBody: function() {
  1061. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  1062. }.property(),
  1063. lastComponent: function() {
  1064. if (lastComponents && lastComponents.length) {
  1065. this.set('enablePrimary',false);
  1066. return true;
  1067. } else {
  1068. this.set('enablePrimary',true);
  1069. return false;
  1070. }
  1071. }.property(),
  1072. enablePrimary: false,
  1073. lastComponentError: Em.View.extend({
  1074. template: Ember.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  1075. }),
  1076. unknownComponents: function() {
  1077. if (unknownComponents && unknownComponents.length) {
  1078. return unknownComponents.join(", ");
  1079. }
  1080. return '';
  1081. }.property(),
  1082. bodyClass: Em.View.extend({
  1083. templateName: require('templates/main/host/details/doDeleteHostPopup')
  1084. }),
  1085. onPrimary: function() {
  1086. if (!this.get('enablePrimary')) return;
  1087. self.set('fromDeleteHost', true);
  1088. var allComponents = self.get('content.hostComponents');
  1089. var deleteError = null;
  1090. allComponents.forEach(function(component){
  1091. if (!deleteError) {
  1092. deleteError = self._doDeleteHostComponent(component);
  1093. }
  1094. });
  1095. if (!deleteError) {
  1096. App.ajax.send({
  1097. name: 'host.delete',
  1098. sender: this,
  1099. data: {
  1100. hostName: self.get('content.hostName')
  1101. },
  1102. success: 'deleteHostSuccessCallback',
  1103. error: 'deleteHostErrorCallback'
  1104. });
  1105. }
  1106. else {
  1107. this.hide();
  1108. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  1109. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  1110. }
  1111. },
  1112. deleteHostSuccessCallback: function(data) {
  1113. var dialogSelf = this;
  1114. App.router.get('updateController').updateHost(function(){
  1115. self.loadConfigs();
  1116. dialogSelf.hide();
  1117. App.router.transitionTo('hosts.index');
  1118. });
  1119. },
  1120. deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) {
  1121. console.log('Error deleting host.');
  1122. console.log(textStatus);
  1123. console.log(errorThrown);
  1124. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  1125. self.loadConfigs();
  1126. this.hide();
  1127. App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status);
  1128. }
  1129. })
  1130. },
  1131. restartAllStaleConfigComponents: function() {
  1132. var staleComponents = this.get('content.componentsWithStaleConfigs');
  1133. batchUtils.restartHostComponents(staleComponents);
  1134. },
  1135. /**
  1136. * open Reassign Master Wizard with selected component
  1137. * @param event
  1138. */
  1139. moveComponent: function (event) {
  1140. App.showConfirmationPopup(function() {
  1141. var component = event.context;
  1142. var reassignMasterController = App.router.get('reassignMasterController');
  1143. reassignMasterController.saveComponentToReassign(component);
  1144. reassignMasterController.getSecurityStatus();
  1145. reassignMasterController.setCurrentStep('1');
  1146. App.router.transitionTo('services.reassign');
  1147. });
  1148. },
  1149. turnOnOffPassiveConfirmation: function(event){
  1150. var self = this;
  1151. var component = event.context;
  1152. var state, onOff;
  1153. if (component.get("passiveState") == "PASSIVE") {
  1154. onOff = "Off";
  1155. state = "ACTIVE";
  1156. } else {
  1157. onOff = "On";
  1158. state = "PASSIVE";
  1159. }
  1160. App.showConfirmationPopup(function() {
  1161. self.turnOnOffPassive(state, component)
  1162. },
  1163. Em.I18n.t('hosts.passiveMode.popup').format(onOff,component.get('displayName'))
  1164. );
  1165. },
  1166. turnOnOffPassive: function(state,component) {
  1167. var hostName = this.get('content.hostName');
  1168. App.ajax.send({
  1169. name: 'host_component.passive',
  1170. sender: this,
  1171. data: {
  1172. component: component,
  1173. hostName: hostName,
  1174. componentName: component.get('componentName'),
  1175. passive_state: state,
  1176. requestInfo: component.get('componentName') + " " + state
  1177. },
  1178. success: 'updateComponentPassiveState'
  1179. });
  1180. },
  1181. updateComponentPassiveState: function(data, opt, params) {
  1182. params.component.set('passiveState',params.passive_state);
  1183. },
  1184. /**
  1185. * Restart clients host components to apply config changes
  1186. */
  1187. refreshConfigs: function(event) {
  1188. var components = event.context.filter(function(component) {
  1189. return component.get('staleConfigs');
  1190. });
  1191. if (components.get('length') > 0) {
  1192. App.showConfirmationPopup(function() {
  1193. batchUtils.restartHostComponents(components);
  1194. });
  1195. }
  1196. }
  1197. });