details.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. App.MainHostDetailsController = Em.Controller.extend({
  20. name: 'mainHostDetailsController',
  21. content: null,
  22. isFromHosts: false,
  23. /**
  24. * open dashboard page
  25. */
  26. routeHome: function () {
  27. App.router.transitionTo('main.dashboard');
  28. },
  29. /**
  30. * open summary page of the selected service
  31. * @param event
  32. */
  33. routeToService: function(event){
  34. var service = event.context;
  35. App.router.transitionTo('main.services.service.summary',service);
  36. },
  37. /**
  38. * set new value to isFromHosts property
  39. * @param isFromHosts new value
  40. */
  41. setBack: function(isFromHosts){
  42. this.set('isFromHosts', isFromHosts);
  43. },
  44. /**
  45. * Send specific command to server
  46. * @param url
  47. * @param _method
  48. * @param postData
  49. * @param callback
  50. */
  51. sendCommandToServer : function(url, postData, _method, callback){
  52. var url = (App.testMode) ?
  53. '/data/wizard/deploy/poll_1.json' : //content is the same as ours
  54. App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  55. var method = App.testMode ? 'GET' : _method;
  56. $.ajax({
  57. type: method,
  58. url: url,
  59. data: JSON.stringify(postData),
  60. dataType: 'json',
  61. timeout: App.timeout,
  62. success: function(data){
  63. if(data && data.Requests){
  64. callback(data.Requests.id);
  65. } else{
  66. callback(null);
  67. console.log('cannot get request id from ', data);
  68. }
  69. },
  70. error: function (request, ajaxOptions, error) {
  71. //do something
  72. console.log('error on change component host status');
  73. App.ajax.defaultErrorHandler(request, url, method);
  74. },
  75. statusCode: require('data/statusCodes')
  76. });
  77. },
  78. /**
  79. * send command to server to start selected host component
  80. * @param event
  81. */
  82. startComponent: function (event) {
  83. var self = this;
  84. App.showConfirmationPopup(function() {
  85. var component = event.context;
  86. var context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
  87. self.sendStartComponentCommand(component, context);
  88. });
  89. },
  90. /**
  91. * PUTs a command to server to start a component. If no
  92. * specific component is provided, all components are started.
  93. * @param component When <code>null</code> all startable components are started.
  94. * @param context Context under which this command is beign sent.
  95. */
  96. sendStartComponentCommand: function(component, context) {
  97. var url = component !== null ?
  98. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  99. '/hosts/' + this.get('content.hostName') + '/host_components';
  100. var dataToSend = {
  101. RequestInfo : {
  102. "context" : context
  103. },
  104. Body:{
  105. HostRoles:{
  106. state: 'STARTED'
  107. }
  108. }
  109. };
  110. if (component === null) {
  111. var allComponents = this.get('content.hostComponents');
  112. var startable = [];
  113. allComponents.forEach(function (c) {
  114. if (c.get('isMaster') || c.get('isSlave')) {
  115. startable.push(c.get('componentName'));
  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. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  145. App.router.get('backgroundOperationsController').showPopup();
  146. }
  147. });
  148. },
  149. /**
  150. * send command to server to delete selected host component
  151. *
  152. */
  153. deleteComponent: function (event) {
  154. var self = this;
  155. var component = event.context;
  156. var componentName = component.get('componentName').toUpperCase().toString();
  157. var displayName = component.get('displayName');
  158. var numberOfComponents = 0;
  159. var isLastComponent = false;
  160. var allComponents = component.get('service.hostComponents');
  161. allComponents.forEach(function(component) {
  162. if (component.get('componentName') == componentName) numberOfComponents++;
  163. if (numberOfComponents > 1) return;
  164. });
  165. if (numberOfComponents == 1) {
  166. isLastComponent = true;
  167. }
  168. App.ModalPopup.show({
  169. header: Em.I18n.t('popup.confirmation.commonHeader'),
  170. bodyClass: Ember.View.extend({
  171. templateName: require('templates/main/host/details/deleteComponentPopup')
  172. }),
  173. enablePrimary: false,
  174. lastComponent: function() {
  175. if (isLastComponent) {
  176. this.set('enablePrimary',false);
  177. return true;
  178. } else {
  179. this.set('enablePrimary',true);
  180. return false;
  181. }
  182. }.property(),
  183. lastComponentError: Em.View.extend({
  184. template: Ember.Handlebars.compile(Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName))
  185. }),
  186. deleteComponentMsg: function() {
  187. return Em.I18n.t('hosts.host.deleteComponent.popup.msg').format(displayName);
  188. }.property(),
  189. onPrimary: function () {
  190. if (!this.get('enablePrimary')) return;
  191. self._doDeleteHostComponent(component);
  192. this.hide();
  193. },
  194. });
  195. },
  196. /**
  197. * Deletes the given host component, or all host components.
  198. *
  199. * @param component When <code>null</code> all host components are deleted.
  200. * @return <code>null</code> when components get deleted.
  201. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  202. * when components failed to get deleted.
  203. */
  204. _doDeleteHostComponent: function(component) {
  205. var url = component !== null ?
  206. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  207. '/hosts/' + this.get('content.hostName') + '/host_components';
  208. url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  209. var deleted = null;
  210. $.ajax({
  211. type: 'DELETE',
  212. url: url,
  213. timeout: App.timeout,
  214. async: false,
  215. success: function (data) {
  216. deleted = null;
  217. },
  218. error: function (xhr, textStatus, errorThrown) {
  219. console.log('Error deleting host component');
  220. console.log(textStatus);
  221. console.log(errorThrown);
  222. deleted = {xhr: xhr, url: url, method: 'DELETE'};
  223. },
  224. statusCode: require('data/statusCodes')
  225. });
  226. return deleted;
  227. },
  228. /**
  229. * send command to server to upgrade selected host component
  230. * @param event
  231. */
  232. upgradeComponent: function (event) {
  233. var self = this;
  234. var component = event.context;
  235. App.showConfirmationPopup(function() {
  236. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(),{
  237. RequestInfo : {
  238. "context" : Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  239. },
  240. Body:{
  241. HostRoles:{
  242. stack_id: 'HDP-1.2.2',
  243. state: 'INSTALLED'
  244. }
  245. }
  246. }, 'PUT',
  247. function(requestId){
  248. if(!requestId){
  249. return;
  250. }
  251. console.log('Send request for UPGRADE successfully');
  252. if (App.testMode) {
  253. component.set('workStatus', App.HostComponentStatus.starting);
  254. setTimeout(function(){
  255. component.set('workStatus', App.HostComponentStatus.started);
  256. },App.testModeDelayForActions);
  257. } else {
  258. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  259. }
  260. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  261. App.router.get('backgroundOperationsController').showPopup();
  262. }
  263. });
  264. });
  265. },
  266. /**
  267. * send command to server to stop selected host component
  268. * @param event
  269. */
  270. stopComponent: function (event) {
  271. var self = this;
  272. App.showConfirmationPopup(function() {
  273. var component = event.context;
  274. var context = Em.I18n.t('requestInfo.stopHostComponent')+ " " + component.get('displayName');
  275. self.sendStopComponentCommand(component, context);
  276. });
  277. },
  278. /**
  279. * PUTs a command to server to stop a component. If no
  280. * specific component is provided, all components are stopped.
  281. * @param component When <code>null</code> all components are stopped.
  282. * @param context Context under which this command is beign sent.
  283. */
  284. sendStopComponentCommand: function(component, context){
  285. var url = component !== null ?
  286. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  287. '/hosts/' + this.get('content.hostName') + '/host_components';
  288. var dataToSend = {
  289. RequestInfo : {
  290. "context" : context
  291. },
  292. Body:{
  293. HostRoles:{
  294. state: 'INSTALLED'
  295. }
  296. }
  297. };
  298. if (component === null) {
  299. var allComponents = this.get('content.hostComponents');
  300. var startable = [];
  301. allComponents.forEach(function (c) {
  302. if (c.get('isMaster') || c.get('isSlave')) {
  303. startable.push(c.get('componentName'));
  304. }
  305. });
  306. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + startable.join(',') + ")";
  307. }
  308. this.sendCommandToServer( url, dataToSend, 'PUT',
  309. function(requestId){
  310. if(!requestId){
  311. return;
  312. }
  313. console.log('Send request for STOPPING successfully');
  314. if (App.testMode) {
  315. if(component === null){
  316. var allComponents = this.get('content.hostComponents');
  317. allComponents.forEach(function(component){
  318. component.set('workStatus', App.HostComponentStatus.stopping);
  319. setTimeout(function(){
  320. component.set('workStatus', App.HostComponentStatus.stopped);
  321. },App.testModeDelayForActions);
  322. });
  323. } else {
  324. component.set('workStatus', App.HostComponentStatus.stopping);
  325. setTimeout(function(){
  326. component.set('workStatus', App.HostComponentStatus.stopped);
  327. },App.testModeDelayForActions);
  328. }
  329. } else {
  330. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  331. }
  332. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  333. App.router.get('backgroundOperationsController').showPopup();
  334. }
  335. });
  336. },
  337. /**
  338. * send command to server to install selected host component
  339. * @param event
  340. */
  341. addComponent: function (event, context) {
  342. var self = this;
  343. var component = event.context;
  344. var componentName = component.get('componentName').toUpperCase().toString();
  345. var subComponentNames = component.get('subComponentNames');
  346. var displayName = component.get('displayName');
  347. var securityEnabled = App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus();
  348. if (securityEnabled) {
  349. App.showConfirmationPopup(function() {
  350. self.primary(component);
  351. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName,self.get('content.hostName')));
  352. }
  353. else {
  354. var dn = displayName;
  355. if (subComponentNames !== null && subComponentNames.length > 0) {
  356. var dns = [];
  357. subComponentNames.forEach(function(scn){
  358. dns.push(App.format.role(scn));
  359. });
  360. dn += " ("+dns.join(", ")+")";
  361. }
  362. App.ModalPopup.show({
  363. primary: Em.I18n.t('yes'),
  364. secondary: Em.I18n.t('no'),
  365. header: Em.I18n.t('popup.confirmation.commonHeader'),
  366. addComponentMsg: function() {
  367. return Em.I18n.t('hosts.host.addComponent.msg').format(dn);
  368. }.property(),
  369. bodyClass: Ember.View.extend({
  370. templateName: require('templates/main/host/details/addComponentPopup')
  371. }),
  372. onPrimary: function () {
  373. this.hide();
  374. if (component.get('componentName') === 'CLIENTS') {
  375. // Clients component has many sub-components which
  376. // need to be installed.
  377. var scs = component.get('subComponentNames');
  378. scs.forEach(function (sc) {
  379. var c = Em.Object.create({
  380. displayName: App.format.role(sc),
  381. componentName: sc
  382. });
  383. self.primary(c);
  384. });
  385. } else {
  386. self.primary(component);
  387. }
  388. }
  389. });
  390. }
  391. },
  392. primary: function(component) {
  393. var self = this;
  394. var componentName = component.get('componentName').toUpperCase().toString();
  395. var displayName = component.get('displayName');
  396. self.sendCommandToServer('/hosts?Hosts/host_name=' + self.get('content.hostName'), {
  397. RequestInfo: {
  398. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  399. },
  400. Body: {
  401. host_components: [
  402. {
  403. HostRoles: {
  404. component_name: componentName
  405. }
  406. }
  407. ]
  408. }
  409. },
  410. 'POST',
  411. function (requestId) {
  412. console.log('Send request for ADDING NEW COMPONENT successfully');
  413. self.sendCommandToServer('/host_components?HostRoles/host_name=' + self.get('content.hostName') + '\&HostRoles/component_name=' + componentName + '\&HostRoles/state=INIT', {
  414. RequestInfo: {
  415. "context": Em.I18n.t('requestInfo.installNewHostComponent') + " " + displayName
  416. },
  417. Body: {
  418. HostRoles: {
  419. state: 'INSTALLED'
  420. }
  421. }
  422. },
  423. 'PUT',
  424. function (requestId) {
  425. if (!requestId) {
  426. return;
  427. }
  428. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  429. if (App.testMode) {
  430. component.set('workStatus', App.HostComponentStatus.installing);
  431. setTimeout(function () {
  432. component.set('workStatus', App.HostComponentStatus.stopped);
  433. }, App.testModeDelayForActions);
  434. } else {
  435. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  436. }
  437. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  438. App.router.get('backgroundOperationsController').showPopup();
  439. }
  440. });
  441. });
  442. },
  443. /**
  444. * send command to server to install selected host component
  445. * @param event
  446. * @param context
  447. */
  448. installComponent: function (event, context) {
  449. var self = this;
  450. var component = event.context;
  451. var componentName = component.get('componentName').toUpperCase().toString();
  452. var displayName = component.get('displayName');
  453. App.ModalPopup.show({
  454. primary: Em.I18n.t('yes'),
  455. secondary: Em.I18n.t('no'),
  456. header: Em.I18n.t('popup.confirmation.commonHeader'),
  457. installComponentMessage: function(){
  458. return Em.I18n.t('hosts.host.installComponent.msg').format(displayName);
  459. }.property(),
  460. bodyClass: Ember.View.extend({
  461. templateName: require('templates/main/host/details/installComponentPopup')
  462. }),
  463. onPrimary: function () {
  464. this.hide();
  465. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(), {
  466. RequestInfo: {
  467. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  468. },
  469. Body: {
  470. HostRoles: {
  471. state: 'INSTALLED'
  472. }
  473. }
  474. },
  475. 'PUT',
  476. function (requestId) {
  477. if (!requestId) {
  478. return;
  479. }
  480. console.log('Send request for REINSTALL COMPONENT successfully');
  481. if (App.testMode) {
  482. component.set('workStatus', App.HostComponentStatus.installing);
  483. setTimeout(function () {
  484. component.set('workStatus', App.HostComponentStatus.stopped);
  485. }, App.testModeDelayForActions);
  486. } else {
  487. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  488. }
  489. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  490. App.router.get('backgroundOperationsController').showPopup();
  491. }
  492. });
  493. }
  494. });
  495. },
  496. /**
  497. * send command to server to run decommission on DATANODE
  498. * @param event
  499. */
  500. decommission: function(event){
  501. var self = this;
  502. var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
  503. if (decommissionHostNames == null) {
  504. decommissionHostNames = [];
  505. }
  506. App.showConfirmationPopup(function(){
  507. var component = event.context;
  508. // Only HDFS service as of now
  509. var svcName = component.get('service.serviceName');
  510. if (svcName === "HDFS") {
  511. var hostName = self.get('content.hostName');
  512. var index = decommissionHostNames.indexOf(hostName);
  513. if (index < 0) {
  514. decommissionHostNames.push(hostName);
  515. }
  516. self.doDatanodeDecommission(decommissionHostNames, true);
  517. }
  518. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  519. App.router.get('backgroundOperationsController').showPopup();
  520. }
  521. });
  522. },
  523. /**
  524. * Performs either Decommission or Recommission by updating the hosts list on
  525. * server.
  526. * @param decommission defines context for request (true for decommission and false for recommission)
  527. */
  528. doDatanodeDecommission: function(decommissionHostNames, decommission){
  529. var self = this;
  530. if (decommissionHostNames == null) {
  531. decommissionHostNames = [];
  532. }
  533. var invocationTag = String(new Date().getTime());
  534. var context = decommission ? Em.I18n.t('hosts.host.datanode.decommission') : Em.I18n.t('hosts.host.datanode.recommission');
  535. var clusterName = App.router.get('clusterController.clusterName');
  536. var clusterUrl = App.apiPrefix + '/clusters/' + clusterName;
  537. var configsUrl = clusterUrl + '/configurations';
  538. var configsData = {
  539. type: "hdfs-exclude-file",
  540. tag: invocationTag,
  541. properties: {
  542. datanodes: decommissionHostNames.join(',')
  543. }
  544. };
  545. var configsAjax = {
  546. type: 'POST',
  547. url: configsUrl,
  548. dataType: 'json',
  549. data: JSON.stringify(configsData),
  550. timeout: App.timeout,
  551. success: function(){
  552. var actionsUrl = clusterUrl + '/services/HDFS/actions/DECOMMISSION_DATANODE';
  553. var actionsData = {
  554. RequestInfo: {
  555. context: context},
  556. Body: {
  557. parameters: {
  558. excludeFileTag: invocationTag
  559. }
  560. }
  561. };
  562. var actionsAjax = {
  563. type: 'POST',
  564. url: actionsUrl,
  565. dataType: 'json',
  566. data: JSON.stringify(actionsData),
  567. timeout: App.timeout,
  568. success: function(){
  569. var persistUrl = App.apiPrefix + '/persist';
  570. var persistData = {
  571. "decommissionDataNodesTag": invocationTag
  572. };
  573. var persistPutAjax = {
  574. type: 'POST',
  575. url: persistUrl,
  576. dataType: 'json',
  577. data: JSON.stringify(persistData),
  578. timeout: App.timeout,
  579. success: function(){
  580. var view = self.get('view');
  581. view.loadDecommissionNodesList();
  582. }
  583. };
  584. jQuery.ajax(persistPutAjax);
  585. },
  586. error: function(xhr, textStatus, errorThrown){
  587. console.log(textStatus);
  588. console.log(errorThrown);
  589. }
  590. };
  591. jQuery.ajax(actionsAjax);
  592. },
  593. error: function(xhr, textStatus, errorThrown){
  594. console.log(textStatus);
  595. console.log(errorThrown);
  596. }
  597. };
  598. jQuery.ajax(configsAjax);
  599. },
  600. /**
  601. * send command to server to run recommission on DATANODE
  602. * @param event
  603. */
  604. recommission: function(event){
  605. var self = this;
  606. var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
  607. if (decommissionHostNames == null) {
  608. decommissionHostNames = [];
  609. }
  610. App.showConfirmationPopup(function(){
  611. var component = event.context;
  612. // Only HDFS service as of now
  613. var svcName = component.get('service.serviceName');
  614. if (svcName === "HDFS") {
  615. var hostName = self.get('content.hostName');
  616. var index = decommissionHostNames.indexOf(hostName);
  617. decommissionHostNames.splice(index, 1);
  618. self.doDatanodeDecommission(decommissionHostNames, false);
  619. }
  620. if (App.router.get('mainAdminUserSettingsController').loadShowBgChecked()) {
  621. App.router.get('backgroundOperationsController').showPopup();
  622. }
  623. });
  624. },
  625. doAction: function(option) {
  626. switch (option.context.action) {
  627. case "deleteHost":
  628. this.validateAndDeleteHost();
  629. break;
  630. case "startAllComponents":
  631. this.doStartAllComponents();
  632. break;
  633. case "stopAllComponents":
  634. this.doStopAllComponents();
  635. break;
  636. default:
  637. break;
  638. }
  639. },
  640. doStartAllComponents: function() {
  641. var self = this;
  642. var components = this.get('content.hostComponents');
  643. var componentsLength = components == null ? 0 : components.get('length');
  644. if (componentsLength > 0) {
  645. App.showConfirmationPopup(function() {
  646. self.sendStartComponentCommand(null,
  647. Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  648. });
  649. }
  650. },
  651. doStopAllComponents: function() {
  652. var self = this;
  653. var components = this.get('content.hostComponents');
  654. var componentsLength = components == null ? 0 : components.get('length');
  655. if (componentsLength > 0) {
  656. App.showConfirmationPopup(function() {
  657. self.sendStopComponentCommand(null,
  658. Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  659. });
  660. }
  661. },
  662. /**
  663. * Deletion of hosts not supported for this version
  664. */
  665. validateAndDeleteHost: function () {
  666. if (!App.supports.deleteHost) {
  667. return;
  668. }
  669. var stoppedStates = [App.HostComponentStatus.stopped,
  670. App.HostComponentStatus.install_failed,
  671. App.HostComponentStatus.upgrade_failed,
  672. App.HostComponentStatus.unknown];
  673. var masterComponents = [];
  674. var runningComponents = [];
  675. var unknownComponents = [];
  676. var nonDeletableComponents = [];
  677. var lastComponents = [];
  678. var components = this.get('content.hostComponents');
  679. if (components!=null && components.get('length')>0){
  680. components.forEach(function (cInstance) {
  681. var numberOfComponents = 0;
  682. var allComponents = cInstance.get('service.hostComponents');
  683. allComponents.forEach(function(component) {
  684. if (component.get('componentName') == cInstance.get('componentName')) numberOfComponents++;
  685. if (numberOfComponents > 1) return;
  686. });
  687. if (numberOfComponents == 1) {
  688. lastComponents.push(cInstance.get('displayName'));
  689. }
  690. var workStatus = cInstance.get('workStatus');
  691. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  692. masterComponents.push(cInstance.get('displayName'));
  693. }
  694. if (stoppedStates.indexOf(workStatus) < 0) {
  695. runningComponents.push(cInstance.get('displayName'));
  696. }
  697. if (!cInstance.get('isDeletable')) {
  698. nonDeletableComponents.push(cInstance.get('displayName'));
  699. }
  700. if (workStatus === App.HostComponentStatus.unknown) {
  701. unknownComponents.push(cInstance.get('displayName'));
  702. }
  703. });
  704. }
  705. if (masterComponents.length > 0) {
  706. this.raiseDeleteComponentsError(masterComponents, 'masterList');
  707. return;
  708. } else if (nonDeletableComponents.length > 0) {
  709. this.raiseDeleteComponentsError(nonDeletableComponents, 'nonDeletableList');
  710. return;
  711. } else if(runningComponents.length > 0) {
  712. this.raiseDeleteComponentsError(runningComponents, 'runningList');
  713. return;
  714. }
  715. this._doDeleteHost(unknownComponents,lastComponents);
  716. },
  717. raiseDeleteComponentsError: function (components, type) {
  718. App.ModalPopup.show({
  719. header: Em.I18n.t('hosts.cant.do.popup.title'),
  720. type: type,
  721. showBodyEnd: function() {
  722. return this.get('type') === 'runningList' || this.get('type') === 'masterList';
  723. }.property(),
  724. components: components,
  725. componentsStr: function() {
  726. return this.get('components').join(", ");
  727. }.property(),
  728. componentsBody: function() {
  729. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body').format(this.get('components').length);
  730. }.property(),
  731. componentsBodyEnd: function() {
  732. if (this.get('showBodyEnd')) {
  733. return Em.I18n.t('hosts.cant.do.popup.'+type+'.body.end');
  734. }
  735. return '';
  736. }.property(),
  737. bodyClass: Em.View.extend({
  738. templateName: require('templates/main/host/details/raiseDeleteComponentErrorPopup')
  739. }),
  740. secondary: null
  741. })
  742. },
  743. /**
  744. * show confirmation popup to delete host
  745. */
  746. _doDeleteHost: function(unknownComponents,lastComponents) {
  747. var self = this;
  748. App.ModalPopup.show({
  749. header: Em.I18n.t('hosts.delete.popup.title'),
  750. deletePopupBody: function() {
  751. return Em.I18n.t('hosts.delete.popup.body').format(self.get('content.publicHostName'));
  752. }.property(),
  753. lastComponent: function() {
  754. if (lastComponents && lastComponents.length) {
  755. this.set('enablePrimary',false);
  756. return true;
  757. } else {
  758. this.set('enablePrimary',true);
  759. return false;
  760. }
  761. }.property(),
  762. enablePrimary: false,
  763. lastComponentError: Em.View.extend({
  764. template: Ember.Handlebars.compile(Em.I18n.t('hosts.delete.popup.body.msg4').format(lastComponents))
  765. }),
  766. unknownComponents: function() {
  767. if (unknownComponents && unknownComponents.length) {
  768. return unknownComponents.join(", ");
  769. }
  770. return '';
  771. }.property(),
  772. bodyClass: Em.View.extend({
  773. templateName: require('templates/main/host/details/doDeleteHostPopup')
  774. }),
  775. onPrimary: function() {
  776. if (!this.get('enablePrimary')) return;
  777. var dialogSelf = this;
  778. var allComponents = self.get('content.hostComponents');
  779. var deleteError = null;
  780. allComponents.forEach(function(component){
  781. if (!deleteError) {
  782. deleteError = self._doDeleteHostComponent(component);
  783. }
  784. });
  785. if (!deleteError) {
  786. var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/hosts/' + self.get('content.hostName');
  787. $.ajax({
  788. type: 'DELETE',
  789. url: url,
  790. timeout: App.timeout,
  791. async: false,
  792. success: function (data) {
  793. dialogSelf.hide();
  794. App.router.get('updateController').updateAll();
  795. App.router.transitionTo('hosts.index');
  796. },
  797. error: function (xhr, textStatus, errorThrown) {
  798. console.log('Error deleting host component');
  799. console.log(textStatus);
  800. console.log(errorThrown);
  801. dialogSelf.hide();
  802. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  803. App.ajax.defaultErrorHandler(xhr, url, 'DELETE', xhr.status);
  804. },
  805. statusCode: require('data/statusCodes')
  806. });
  807. } else {
  808. dialogSelf.hide();
  809. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  810. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  811. }
  812. },
  813. onSecondary: function() {
  814. this.hide();
  815. }
  816. })
  817. },
  818. restartComponents: function() {
  819. App.showConfirmationPopup(function() {
  820. });
  821. }
  822. });