details.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  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. App.router.get('backgroundOperationsController').showPopup();
  145. });
  146. },
  147. /**
  148. * Deletes the given host component, or all host components.
  149. *
  150. * @param component When <code>null</code> all host components are deleted.
  151. * @return <code>null</code> when components get deleted.
  152. * <code>{xhr: XhrObj, url: "http://", method: "DELETE"}</code>
  153. * when components failed to get deleted.
  154. */
  155. _doDeleteHostComponent: function(component) {
  156. var url = component !== null ?
  157. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  158. '/hosts/' + this.get('content.hostName') + '/host_components';
  159. url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  160. var deleted = null;
  161. $.ajax({
  162. type: 'DELETE',
  163. url: url,
  164. timeout: App.timeout,
  165. async: false,
  166. success: function (data) {
  167. deleted = null;
  168. // If ZooKeeper Server component was removed,
  169. // restart ZooKeeper service.
  170. /*
  171. * Commenting it out as user can restart service
  172. * whenever they want. We mention in message.
  173. if (component.get('componentName') === 'ZOOKEEPER_SERVER') {
  174. App.ajax.send({
  175. 'name': 'service.item.start_stop',
  176. 'sender': this,
  177. 'data': {
  178. 'requestInfo': 'Stop ZooKeeper',
  179. 'serviceName': 'ZOOKEEPER',
  180. 'state': 'INSTALLED'
  181. },
  182. 'callback': function() {
  183. App.ajax.send({
  184. 'name': 'service.item.start_stop',
  185. 'sender': this,
  186. 'data': {
  187. 'requestInfo': 'Start ZooKeeper',
  188. 'serviceName': 'ZOOKEEPER',
  189. 'state': 'STARTED'
  190. }
  191. });
  192. }
  193. });
  194. }*/
  195. },
  196. error: function (xhr, textStatus, errorThrown) {
  197. console.log('Error deleting host component');
  198. console.log(textStatus);
  199. console.log(errorThrown);
  200. deleted = {xhr: xhr, url: url, method: 'DELETE'};
  201. },
  202. statusCode: require('data/statusCodes')
  203. });
  204. return deleted;
  205. },
  206. /**
  207. * send command to server to upgrade selected host component
  208. * @param event
  209. */
  210. upgradeComponent: function (event) {
  211. var self = this;
  212. var component = event.context;
  213. App.showConfirmationPopup(function() {
  214. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(),{
  215. RequestInfo : {
  216. "context" : Em.I18n.t('requestInfo.upgradeHostComponent') + " " + component.get('displayName')
  217. },
  218. Body:{
  219. HostRoles:{
  220. stack_id: 'HDP-1.2.2',
  221. state: 'INSTALLED'
  222. }
  223. }
  224. }, 'PUT',
  225. function(requestId){
  226. if(!requestId){
  227. return;
  228. }
  229. console.log('Send request for UPGRADE successfully');
  230. if (App.testMode) {
  231. component.set('workStatus', App.HostComponentStatus.starting);
  232. setTimeout(function(){
  233. component.set('workStatus', App.HostComponentStatus.started);
  234. },App.testModeDelayForActions);
  235. } else {
  236. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  237. }
  238. App.router.get('backgroundOperationsController').showPopup();
  239. });
  240. });
  241. },
  242. /**
  243. * send command to server to stop selected host component
  244. * @param event
  245. */
  246. stopComponent: function (event) {
  247. var self = this;
  248. App.showConfirmationPopup(function() {
  249. var component = event.context;
  250. var context = Em.I18n.t('requestInfo.stopHostComponent')+ " " + component.get('displayName');
  251. self.sendStopComponentCommand(component, context);
  252. });
  253. },
  254. /**
  255. * PUTs a command to server to stop a component. If no
  256. * specific component is provided, all components are stopped.
  257. * @param component When <code>null</code> all components are stopped.
  258. * @param context Context under which this command is beign sent.
  259. */
  260. sendStopComponentCommand: function(component, context){
  261. var url = component !== null ?
  262. '/hosts/' + this.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase() :
  263. '/hosts/' + this.get('content.hostName') + '/host_components';
  264. var dataToSend = {
  265. RequestInfo : {
  266. "context" : context
  267. },
  268. Body:{
  269. HostRoles:{
  270. state: 'INSTALLED'
  271. }
  272. }
  273. };
  274. if (component === null) {
  275. var allComponents = this.get('content.hostComponents');
  276. var startable = [];
  277. allComponents.forEach(function (c) {
  278. if (c.get('isMaster') || c.get('isSlave')) {
  279. startable.push(c.get('componentName'));
  280. }
  281. });
  282. dataToSend.RequestInfo.query = "HostRoles/component_name.in(" + startable.join(',') + ")";
  283. }
  284. this.sendCommandToServer( url, dataToSend, 'PUT',
  285. function(requestId){
  286. if(!requestId){
  287. return;
  288. }
  289. console.log('Send request for STOPPING successfully');
  290. if (App.testMode) {
  291. if(component === null){
  292. var allComponents = this.get('content.hostComponents');
  293. allComponents.forEach(function(component){
  294. component.set('workStatus', App.HostComponentStatus.stopping);
  295. setTimeout(function(){
  296. component.set('workStatus', App.HostComponentStatus.stopped);
  297. },App.testModeDelayForActions);
  298. });
  299. } else {
  300. component.set('workStatus', App.HostComponentStatus.stopping);
  301. setTimeout(function(){
  302. component.set('workStatus', App.HostComponentStatus.stopped);
  303. },App.testModeDelayForActions);
  304. }
  305. } else {
  306. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  307. }
  308. App.router.get('backgroundOperationsController').showPopup();
  309. });
  310. },
  311. /**
  312. * send command to server to install selected host component
  313. * @param event
  314. */
  315. addComponent: function (event, context) {
  316. var self = this;
  317. var component = event.context;
  318. var componentName = component.get('componentName').toUpperCase().toString();
  319. var subComponentNames = component.get('subComponentNames');
  320. var displayName = component.get('displayName');
  321. var securityEnabled = App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus();
  322. if (securityEnabled) {
  323. App.showConfirmationPopup(function() {
  324. self.primary(component);
  325. }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName,self.get('content.hostName')));
  326. }
  327. else {
  328. var dn = displayName;
  329. if (subComponentNames !== null && subComponentNames.length > 0) {
  330. var dns = [];
  331. subComponentNames.forEach(function(scn){
  332. dns.push(App.format.role(scn));
  333. });
  334. dn += " ("+dns.join(", ")+")";
  335. }
  336. var dialogContent =
  337. [Em.I18n.t('hosts.host.addComponent.msg').format(dn) + "<br><br>",
  338. '{{t hosts.host.addComponent.note}}'];
  339. App.ModalPopup.show({
  340. primary: Em.I18n.t('yes'),
  341. secondary: Em.I18n.t('no'),
  342. header: Em.I18n.t('popup.confirmation.commonHeader'),
  343. bodyClass: Ember.View.extend({
  344. template: Ember.Handlebars.compile(dialogContent.join(''))
  345. }),
  346. onPrimary: function () {
  347. this.hide();
  348. if (component.get('componentName') === 'CLIENTS') {
  349. // Clients component has many sub-components which
  350. // need to be installed.
  351. var scs = component.get('subComponentNames');
  352. scs.forEach(function (sc) {
  353. var c = Em.Object.create({
  354. displayName: App.format.role(sc),
  355. componentName: sc
  356. });
  357. self.primary(c);
  358. });
  359. } else {
  360. self.primary(component);
  361. }
  362. }
  363. });
  364. }
  365. },
  366. primary: function(component) {
  367. var self = this;
  368. var componentName = component.get('componentName').toUpperCase().toString();
  369. var displayName = component.get('displayName');
  370. self.sendCommandToServer('/hosts?Hosts/host_name=' + self.get('content.hostName'), {
  371. RequestInfo: {
  372. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  373. },
  374. Body: {
  375. host_components: [
  376. {
  377. HostRoles: {
  378. component_name: componentName
  379. }
  380. }
  381. ]
  382. }
  383. },
  384. 'POST',
  385. function (requestId) {
  386. console.log('Send request for ADDING NEW COMPONENT successfully');
  387. self.sendCommandToServer('/host_components?HostRoles/host_name=' + self.get('content.hostName') + '\&HostRoles/component_name=' + componentName + '\&HostRoles/state=INIT', {
  388. RequestInfo: {
  389. "context": Em.I18n.t('requestInfo.installNewHostComponent') + " " + displayName
  390. },
  391. Body: {
  392. HostRoles: {
  393. state: 'INSTALLED'
  394. }
  395. }
  396. },
  397. 'PUT',
  398. function (requestId) {
  399. if (!requestId) {
  400. return;
  401. }
  402. console.log('Send request for INSTALLING NEW COMPONENT successfully');
  403. if (App.testMode) {
  404. component.set('workStatus', App.HostComponentStatus.installing);
  405. setTimeout(function () {
  406. component.set('workStatus', App.HostComponentStatus.stopped);
  407. }, App.testModeDelayForActions);
  408. } else {
  409. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  410. }
  411. App.router.get('backgroundOperationsController').showPopup();
  412. });
  413. });
  414. },
  415. /**
  416. * send command to server to install selected host component
  417. * @param event
  418. * @param context
  419. */
  420. installComponent: function (event, context) {
  421. var self = this;
  422. var component = event.context;
  423. var componentName = component.get('componentName').toUpperCase().toString();
  424. var displayName = component.get('displayName');
  425. App.ModalPopup.show({
  426. primary: Em.I18n.t('yes'),
  427. secondary: Em.I18n.t('no'),
  428. header: Em.I18n.t('popup.confirmation.commonHeader'),
  429. bodyClass: Ember.View.extend({
  430. template: Ember.Handlebars.compile([
  431. '{{t hosts.delete.popup.body}}<br /><br />',
  432. '{{t hosts.host.addComponent.note}}'
  433. ].join(''))
  434. }),
  435. onPrimary: function () {
  436. this.hide();
  437. self.sendCommandToServer('/hosts/' + self.get('content.hostName') + '/host_components/' + component.get('componentName').toUpperCase(), {
  438. RequestInfo: {
  439. "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
  440. },
  441. Body: {
  442. HostRoles: {
  443. state: 'INSTALLED'
  444. }
  445. }
  446. },
  447. 'PUT',
  448. function (requestId) {
  449. if (!requestId) {
  450. return;
  451. }
  452. console.log('Send request for REINSTALL COMPONENT successfully');
  453. if (App.testMode) {
  454. component.set('workStatus', App.HostComponentStatus.installing);
  455. setTimeout(function () {
  456. component.set('workStatus', App.HostComponentStatus.stopped);
  457. }, App.testModeDelayForActions);
  458. } else {
  459. App.router.get('clusterController').loadUpdatedStatusDelayed(500);
  460. }
  461. App.router.get('backgroundOperationsController').showPopup();
  462. });
  463. }
  464. });
  465. },
  466. /**
  467. * send command to server to run decommission on DATANODE
  468. * @param event
  469. */
  470. decommission: function(event){
  471. var self = this;
  472. var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
  473. if (decommissionHostNames == null) {
  474. decommissionHostNames = [];
  475. }
  476. App.showConfirmationPopup(function(){
  477. var component = event.context;
  478. // Only HDFS service as of now
  479. var svcName = component.get('service.serviceName');
  480. if (svcName === "HDFS") {
  481. var hostName = self.get('content.hostName');
  482. var index = decommissionHostNames.indexOf(hostName);
  483. if (index < 0) {
  484. decommissionHostNames.push(hostName);
  485. }
  486. self.doDatanodeDecommission(decommissionHostNames, true);
  487. }
  488. App.router.get('backgroundOperationsController').showPopup();
  489. });
  490. },
  491. /**
  492. * Performs either Decommission or Recommission by updating the hosts list on
  493. * server.
  494. * @param decommission defines context for request (true for decommission and false for recommission)
  495. */
  496. doDatanodeDecommission: function(decommissionHostNames, decommission){
  497. var self = this;
  498. if (decommissionHostNames == null) {
  499. decommissionHostNames = [];
  500. }
  501. var invocationTag = String(new Date().getTime());
  502. var context = decommission ? Em.I18n.t('hosts.host.datanode.decommission') : Em.I18n.t('hosts.host.datanode.recommission');
  503. var clusterName = App.router.get('clusterController.clusterName');
  504. var clusterUrl = App.apiPrefix + '/clusters/' + clusterName;
  505. var configsUrl = clusterUrl + '/configurations';
  506. var configsData = {
  507. type: "hdfs-exclude-file",
  508. tag: invocationTag,
  509. properties: {
  510. datanodes: decommissionHostNames.join(',')
  511. }
  512. };
  513. var configsAjax = {
  514. type: 'POST',
  515. url: configsUrl,
  516. dataType: 'json',
  517. data: JSON.stringify(configsData),
  518. timeout: App.timeout,
  519. success: function(){
  520. var actionsUrl = clusterUrl + '/services/HDFS/actions/DECOMMISSION_DATANODE';
  521. var actionsData = {
  522. RequestInfo: {
  523. context: context},
  524. Body: {
  525. parameters: {
  526. excludeFileTag: invocationTag
  527. }
  528. }
  529. };
  530. var actionsAjax = {
  531. type: 'POST',
  532. url: actionsUrl,
  533. dataType: 'json',
  534. data: JSON.stringify(actionsData),
  535. timeout: App.timeout,
  536. success: function(){
  537. var persistUrl = App.apiPrefix + '/persist';
  538. var persistData = {
  539. "decommissionDataNodesTag": invocationTag
  540. };
  541. var persistPutAjax = {
  542. type: 'POST',
  543. url: persistUrl,
  544. dataType: 'json',
  545. data: JSON.stringify(persistData),
  546. timeout: App.timeout,
  547. success: function(){
  548. var view = self.get('view');
  549. view.loadDecommissionNodesList();
  550. }
  551. };
  552. jQuery.ajax(persistPutAjax);
  553. },
  554. error: function(xhr, textStatus, errorThrown){
  555. console.log(textStatus);
  556. console.log(errorThrown);
  557. }
  558. };
  559. jQuery.ajax(actionsAjax);
  560. },
  561. error: function(xhr, textStatus, errorThrown){
  562. console.log(textStatus);
  563. console.log(errorThrown);
  564. }
  565. }
  566. jQuery.ajax(configsAjax);
  567. },
  568. /**
  569. * send command to server to run recommission on DATANODE
  570. * @param event
  571. */
  572. recommission: function(event){
  573. var self = this;
  574. var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
  575. if (decommissionHostNames == null) {
  576. decommissionHostNames = [];
  577. }
  578. App.showConfirmationPopup(function(){
  579. var component = event.context;
  580. // Only HDFS service as of now
  581. var svcName = component.get('service.serviceName');
  582. if (svcName === "HDFS") {
  583. var hostName = self.get('content.hostName');
  584. var index = decommissionHostNames.indexOf(hostName);
  585. decommissionHostNames.splice(index, 1);
  586. self.doDatanodeDecommission(decommissionHostNames, false);
  587. }
  588. App.router.get('backgroundOperationsController').showPopup();
  589. });
  590. },
  591. doAction: function(option) {
  592. switch (option.context.action) {
  593. case "deleteHost":
  594. this.validateAndDeleteHost();
  595. break;
  596. case "startAllComponents":
  597. this.doStartAllComponents();
  598. break;
  599. case "stopAllComponents":
  600. this.doStopAllComponents();
  601. break;
  602. default:
  603. break;
  604. }
  605. },
  606. doStartAllComponents: function() {
  607. var self = this;
  608. var components = this.get('content.hostComponents');
  609. var componentsLength = components == null ? 0 : components.get('length');
  610. if (componentsLength > 0) {
  611. App.showConfirmationPopup(function() {
  612. self.sendStartComponentCommand(null,
  613. Em.I18n.t('hosts.host.maintainance.startAllComponents.context'));
  614. });
  615. }
  616. },
  617. doStopAllComponents: function() {
  618. var self = this;
  619. var components = this.get('content.hostComponents');
  620. var componentsLength = components == null ? 0 : components.get('length');
  621. if (componentsLength > 0) {
  622. App.showConfirmationPopup(function() {
  623. self.sendStopComponentCommand(null,
  624. Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'));
  625. });
  626. }
  627. },
  628. /**
  629. * Deletion of hosts not supported for this version
  630. */
  631. validateAndDeleteHost: function () {
  632. if (!App.supports.deleteHost) {
  633. return;
  634. }
  635. var stoppedStates = [App.HostComponentStatus.stopped,
  636. App.HostComponentStatus.install_failed,
  637. App.HostComponentStatus.upgrade_failed,
  638. App.HostComponentStatus.unknown];
  639. var masterComponents = [];
  640. var runningComponents = [];
  641. var unknownComponents = [];
  642. var nonDeletableComponents = [];
  643. var components = this.get('content.hostComponents');
  644. if (components!=null && components.get('length')>0){
  645. components.forEach(function (cInstance) {
  646. var workStatus = cInstance.get('workStatus');
  647. if (cInstance.get('isMaster') && !cInstance.get('isDeletable')) {
  648. masterComponents.push(cInstance.get('displayName'));
  649. }
  650. if (stoppedStates.indexOf(workStatus) < 0) {
  651. runningComponents.push(cInstance.get('displayName'));
  652. }
  653. if (!cInstance.get('isDeletable')) {
  654. nonDeletableComponents.push(cInstance.get('displayName'));
  655. }
  656. if (workStatus === App.HostComponentStatus.unknown) {
  657. unknownComponents.push(cInstance.get('displayName'));
  658. }
  659. });
  660. }
  661. if (masterComponents.length > 0) {
  662. var bodyHtml = "<p><i class=\"icon-warning-sign\"></i> ";
  663. bodyHtml += Em.I18n.t('hosts.cant.do.popup.masterList.body').format(masterComponents.length);
  664. bodyHtml += "</p><i>";
  665. bodyHtml += masterComponents.join(", ");
  666. bodyHtml += "</i>";
  667. this.raiseDeleteComponentsError(bodyHtml);
  668. return;
  669. } else if (nonDeletableComponents.length > 0) {
  670. var bodyHtml = "<p><i class=\"icon-warning-sign\"></i> ";
  671. bodyHtml += Em.I18n.t('hosts.cant.do.popup.nonDeletableList.body').format(nonDeletableComponents.length);
  672. bodyHtml += "</p><i>";
  673. bodyHtml += nonDeletableComponents.join(", ");
  674. bodyHtml += "</i>";
  675. this.raiseDeleteComponentsError(bodyHtml);
  676. return;
  677. } else if(runningComponents.length > 0) {
  678. var bodyHtml = "<p><i class=\"icon-warning-sign\"></i> ";
  679. bodyHtml += Em.I18n.t('hosts.cant.do.popup.runningList.body').format(runningComponents.length);
  680. bodyHtml += "</p><i>";
  681. bodyHtml += runningComponents.join(", ");
  682. bodyHtml += "</i><br><br><p>";
  683. bodyHtml += Em.I18n.t('hosts.cant.do.popup.runningList.body.end');
  684. bodyHtml += "</p>";
  685. this.raiseDeleteComponentsError(bodyHtml);
  686. return;
  687. }
  688. this._doDeleteHost(unknownComponents);
  689. },
  690. raiseDeleteComponentsError: function (bodyHtml) {
  691. var self = this;
  692. App.ModalPopup.show({
  693. header: Em.I18n.t('hosts.cant.do.popup.title'),
  694. html: true,
  695. encodeBody: false,
  696. body: bodyHtml,
  697. primary: Em.I18n.t('ok'),
  698. secondary: null,
  699. onPrimary: function() {
  700. this.hide();
  701. }
  702. })
  703. },
  704. /**
  705. * show confirmation popup to delete host
  706. */
  707. _doDeleteHost: function(unknownComponents) {
  708. var self = this;
  709. var bodyHtml = "<p><i class=\"icon-warning-sign\"></i> ";
  710. bodyHtml += Em.I18n.t('hosts.delete.popup.body').format("<i>"+this.get('content.publicHostName')+"</i>");
  711. bodyHtml += "</p>";
  712. if (unknownComponents!=null && unknownComponents.length > 0) {
  713. bodyHtml += "<div class=\"alert\">";
  714. bodyHtml += Em.I18n.t('hosts.delete.popup.unknownComponents') + "<br>";
  715. bodyHtml += "<i>"
  716. bodyHtml += unknownComponents.join(", ");
  717. bodyHtml += "</i></div>";
  718. }
  719. bodyHtml += "<p>";
  720. bodyHtml += Em.I18n.t('hosts.delete.popup.body.msg1');
  721. bodyHtml += "</p><p>";
  722. bodyHtml += Em.I18n.t('hosts.delete.popup.body.msg2');
  723. bodyHtml += "</p><p>";
  724. bodyHtml += "<span class=\"label label-important\">"+Em.I18n.t('common.important')+"</span> ";
  725. bodyHtml += Em.I18n.t('hosts.delete.popup.body.msg3');
  726. bodyHtml += "</p>";
  727. App.ModalPopup.show({
  728. header: Em.I18n.t('hosts.delete.popup.title'),
  729. html: true,
  730. encodeBody: false,
  731. body: bodyHtml,
  732. primary: Em.I18n.t('ok'),
  733. secondary: Em.I18n.t('common.cancel'),
  734. onPrimary: function() {
  735. var dialogSelf = this;
  736. var allComponents = self.get('content.hostComponents');
  737. var deleteError = null;
  738. allComponents.forEach(function(component){
  739. if (!deleteError) {
  740. deleteError = self._doDeleteHostComponent(component);
  741. }
  742. });
  743. if (!deleteError) {
  744. var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/hosts/' + self.get('content.hostName');
  745. $.ajax({
  746. type: 'DELETE',
  747. url: url,
  748. timeout: App.timeout,
  749. async: false,
  750. success: function (data) {
  751. dialogSelf.hide();
  752. App.router.get('updateController').updateAll();
  753. App.router.transitionTo('hosts.index');
  754. },
  755. error: function (xhr, textStatus, errorThrown) {
  756. console.log('Error deleting host component');
  757. console.log(textStatus);
  758. console.log(errorThrown);
  759. dialogSelf.hide();
  760. xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}";
  761. App.ajax.defaultErrorHandler(xhr, url, 'DELETE', xhr.status);
  762. },
  763. statusCode: require('data/statusCodes')
  764. });
  765. } else {
  766. dialogSelf.hide();
  767. deleteError.xhr.responseText = "{\"message\": \"" + deleteError.xhr.statusText + "\"}";
  768. App.ajax.defaultErrorHandler(deleteError.xhr, deleteError.url, deleteError.method, deleteError.xhr.status);
  769. }
  770. },
  771. onSecondary: function() {
  772. this.hide();
  773. }
  774. })
  775. }
  776. })