step14_controller.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  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.WizardStep14Controller = Em.Controller.extend({
  20. status: function () {
  21. if (this.get('tasks').someProperty('status', 'FAILED')) {
  22. return 'FAILED';
  23. }
  24. if (this.get('tasks').everyProperty('status', 'COMPLETED')) {
  25. return 'COMPLETED';
  26. }
  27. return 'IN_PROGRESS';
  28. }.property('tasks.@each.status'),
  29. tasks: [],
  30. /**
  31. * Set messages for tasks depending on their status
  32. */
  33. setTasksMessages: function () {
  34. var service = this.get('service.displayName');
  35. var master = this.get('masterComponent.display_name');
  36. for (i = 0; i < this.get('tasks').length; i++) {
  37. var status = this.get('tasks')[i].status.toLowerCase().replace('initialize', 'pending').replace('_', ' ');
  38. if (i == 0 || i == 6) {
  39. this.get('tasks')[i].set('message', Em.I18n.t('installer.step14.task' + i).format(service) + ' ' + status);
  40. } else {
  41. this.get('tasks')[i].set('message', Em.I18n.t('installer.step14.task' + i).format(master) + ' ' + status);
  42. }
  43. }
  44. }.observes('tasks.@each.status'),
  45. configs: [],
  46. globals: [],
  47. configMapping: require('data/config_mapping'),
  48. newConfigsTag: null,
  49. createdConfigs: [],
  50. currentRequestId: null,
  51. isSubmitDisabled: true,
  52. service: function () {
  53. return App.Service.find().findProperty('serviceName', this.get('masterComponent.service_id'));
  54. }.property('masterComponent'),
  55. masterComponent: function () {
  56. return this.get('content.reassign');
  57. }.property('content.reassign'),
  58. loadStep: function () {
  59. this.clearStep();
  60. this.loadTasks();
  61. this.navigateStep();
  62. },
  63. clearStep: function () {
  64. var tasks = [];
  65. for (var i = 0; i < 8; i++) {
  66. tasks.pushObject(Ember.Object.create({
  67. status: 'INITIALIZE',
  68. logs: '',
  69. message: '',
  70. progress: 0
  71. }));
  72. }
  73. this.set('tasks', tasks);
  74. this.set('isSubmitDisabled', true);
  75. this.get('configs').clear();
  76. this.get('globals').clear();
  77. this.get('createdConfigs').clear();
  78. },
  79. loadTasks: function () {
  80. },
  81. /**
  82. * Run tasks in proper way
  83. */
  84. navigateStep: function () {
  85. if (this.get('tasks')[0].status == 'INITIALIZE') {
  86. this.stopService();
  87. }
  88. else if (this.get('tasks')[1].status == 'INITIALIZE') {
  89. this.createMasterComponent();
  90. }
  91. else if (this.taskIsReady(2)) {
  92. this.createConfigs();
  93. }
  94. else if (this.taskIsReady(3)) {
  95. this.applyConfigs();
  96. }
  97. else if (this.taskIsReady(4)) {
  98. this.putInMaintenanceMode();
  99. }
  100. else if (this.taskIsReady(5)) {
  101. this.installComponent();
  102. }
  103. else if (this.taskIsReady(6)) {
  104. this.startComponents();
  105. }
  106. else if (this.taskIsReady(7)) {
  107. this.removeComponent();
  108. }
  109. }.observes('tasks.@each.status'),
  110. /**
  111. * Determine preparedness to run task
  112. * @param task
  113. * @return {Boolean}
  114. */
  115. taskIsReady: function (task) {
  116. var startIndex = (task == 5) ? 0 : 1;
  117. var tempArr = this.get('tasks').mapProperty('status').slice(startIndex, task).uniq();
  118. return this.get('tasks')[task].status == 'INITIALIZE' && tempArr.length == 1 && tempArr[0] == 'COMPLETED';
  119. },
  120. /**
  121. * Change status of the task
  122. * @param task
  123. * @param status
  124. */
  125. setTasksStatus: function (task, status) {
  126. this.get('tasks')[task].set('status', status);
  127. },
  128. stopService: function () {
  129. var self = this;
  130. var clusterName = this.get('content.cluster.name');
  131. var serviceName = this.get('masterComponent.service_id');
  132. var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
  133. var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
  134. var method = 'PUT';
  135. $.ajax({
  136. type: method,
  137. url: url,
  138. data: data,
  139. dataType: 'text',
  140. timeout: App.timeout,
  141. beforeSend: function () {
  142. self.setTasksStatus(0, 'PENDING');
  143. },
  144. success: function (data) {
  145. if (jQuery.parseJSON(data)) {
  146. self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
  147. self.getLogsByRequest();
  148. } else {
  149. self.setTasksStatus(0, 'FAILED');
  150. }
  151. },
  152. error: function () {
  153. self.setTasksStatus(0, 'FAILED');
  154. },
  155. statusCode: require('data/statusCodes')
  156. });
  157. },
  158. createMasterComponent: function () {
  159. var self = this;
  160. var clusterName = this.get('content.cluster.name');
  161. var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
  162. var componentName = this.get('masterComponent.component_name');
  163. var url = App.apiPrefix + '/clusters/' + clusterName + '/hosts?Hosts/host_name=' + hostName;
  164. var data = {
  165. "host_components": [
  166. {
  167. "HostRoles": {
  168. "component_name": componentName
  169. }
  170. }
  171. ]
  172. };
  173. var method = 'POST';
  174. $.ajax({
  175. type: method,
  176. url: url,
  177. data: JSON.stringify(data),
  178. dataType: 'text',
  179. timeout: App.timeout,
  180. beforeSend: function () {
  181. self.setTasksStatus(1, 'PENDING');
  182. },
  183. success: function () {
  184. self.setTasksStatus(1, 'COMPLETED');
  185. },
  186. error: function () {
  187. self.setTasksStatus(1, 'FAILED');
  188. },
  189. statusCode: require('data/statusCodes')
  190. });
  191. },
  192. createConfigs: function () {
  193. this.loadGlobals();
  194. this.loadConfigs();
  195. this.set('newConfigsTag', 'version' + (new Date).getTime());
  196. var serviceName = this.get('service.serviceName');
  197. this.createConfigSite(this.createGlobalSiteObj());
  198. this.createConfigSite(this.createCoreSiteObj());
  199. if (serviceName == 'HDFS') {
  200. this.createConfigSite(this.createHdfsSiteObj());
  201. }
  202. if (serviceName == 'MAPREDUCE') {
  203. this.createConfigSite(this.createMrSiteObj());
  204. }
  205. if (serviceName == 'HBASE') {
  206. this.createConfigSite(this.createHbaseSiteObj());
  207. }
  208. if (serviceName == 'OOZIE') {
  209. this.createConfigSite(this.createOozieSiteObj());
  210. }
  211. if (serviceName == 'HIVE') {
  212. this.createConfigSite(this.createHiveSiteObj());
  213. }
  214. if (serviceName == 'WEBHCAT') {
  215. this.createConfigSite(this.createWebHCatSiteObj());
  216. }
  217. if (this.get('tasks')[2].status !== 'FAILED') {
  218. this.setTasksStatus(2, 'COMPLETED');
  219. }
  220. },
  221. createConfigSite: function (data) {
  222. var self = this;
  223. data.tag = this.get('newConfigsTag');
  224. var clusterName = this.get('content.cluster.name');
  225. var url = App.apiPrefix + '/clusters/' + clusterName + '/configurations';
  226. $.ajax({
  227. type: 'POST',
  228. url: url,
  229. data: JSON.stringify(data),
  230. dataType: 'text',
  231. timeout: 5000,
  232. beforeSend: function () {
  233. self.setTasksStatus(2, 'PENDING');
  234. },
  235. success: function () {
  236. self.get('createdConfigs').push(data.type);
  237. },
  238. error: function () {
  239. self.setTasksStatus(2, 'FAILED');
  240. },
  241. statusCode: require('data/statusCodes')
  242. });
  243. },
  244. loadGlobals: function () {
  245. var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
  246. if (globals.someProperty('name', 'hive_database')) {
  247. //TODO: Hive host depends on the type of db selected. Change puppet variable name if postgres is not the default db
  248. var hiveDb = globals.findProperty('name', 'hive_database');
  249. if (hiveDb.value === 'New MySQL Database') {
  250. if (globals.someProperty('name', 'hive_ambari_host')) {
  251. globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_hostname';
  252. }
  253. globals = globals.without(globals.findProperty('name', 'hive_existing_host'));
  254. globals = globals.without(globals.findProperty('name', 'hive_existing_database'));
  255. } else {
  256. globals.findProperty('name', 'hive_existing_host').name = 'hive_mysql_hostname';
  257. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  258. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  259. }
  260. }
  261. this.set('globals', globals);
  262. },
  263. loadConfigs: function () {
  264. var storedConfigs = this.get('content.serviceConfigProperties').filterProperty('id', 'site property').filterProperty('value');
  265. var uiConfigs = this.loadUiSideConfigs();
  266. this.set('configs', storedConfigs.concat(uiConfigs));
  267. },
  268. loadUiSideConfigs: function () {
  269. var uiConfig = [];
  270. var configs = this.get('configMapping').filterProperty('foreignKey', null);
  271. configs.forEach(function (_config) {
  272. var value = this.getGlobConfigValue(_config.templateName, _config.value, _config.name);
  273. uiConfig.pushObject({
  274. "id": "site property",
  275. "name": _config.name,
  276. "value": value,
  277. "filename": _config.filename
  278. });
  279. }, this);
  280. var dependentConfig = this.get('configMapping').filterProperty('foreignKey');
  281. dependentConfig.forEach(function (_config) {
  282. this.setConfigValue(uiConfig, _config);
  283. uiConfig.pushObject({
  284. "id": "site property",
  285. "name": _config.name,
  286. "value": _config.value,
  287. "filename": _config.filename
  288. });
  289. }, this);
  290. return uiConfig;
  291. },
  292. getGlobConfigValue: function (templateName, expression, name) {
  293. var express = expression.match(/<(.*?)>/g);
  294. var value = expression;
  295. if (express == null) {
  296. return expression;
  297. }
  298. express.forEach(function (_express) {
  299. //console.log("The value of template is: " + _express);
  300. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  301. if (this.get('globals').someProperty('name', templateName[index])) {
  302. //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name);
  303. var globValue = this.get('globals').findProperty('name', templateName[index]).value;
  304. // Hack for templeton.zookeeper.hosts
  305. if (value !== null) { // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
  306. if (name === "templeton.zookeeper.hosts" || name === 'hbase.zookeeper.quorum') {
  307. // globValue is an array of ZooKeeper Server hosts
  308. var zooKeeperPort = '2181';
  309. if (name === "templeton.zookeeper.hosts") {
  310. var zooKeeperServers = globValue.map(function (item) {
  311. return item + ':' + zooKeeperPort;
  312. }).join(',');
  313. value = value.replace(_express, zooKeeperServers);
  314. } else {
  315. value = value.replace(_express, globValue.join(','));
  316. }
  317. } else {
  318. value = value.replace(_express, globValue);
  319. }
  320. }
  321. } else {
  322. /*
  323. console.log("ERROR: The variable name is: " + templateName[index]);
  324. console.log("ERROR: mapped config from configMapping file has no corresponding variable in " +
  325. "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " +
  326. "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable");
  327. */
  328. value = null;
  329. }
  330. }, this);
  331. return value;
  332. },
  333. /**
  334. * Set all site property that are derived from other site-properties
  335. */
  336. setConfigValue: function (uiConfig, config) {
  337. if (config.value == null) {
  338. return;
  339. }
  340. var fkValue = config.value.match(/<(foreignKey.*?)>/g);
  341. if (fkValue) {
  342. fkValue.forEach(function (_fkValue) {
  343. var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
  344. if (uiConfig.someProperty('name', config.foreignKey[index])) {
  345. var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
  346. config.value = config.value.replace(_fkValue, globalValue);
  347. } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
  348. var globalValue;
  349. if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
  350. globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
  351. } else {
  352. globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
  353. }
  354. config.value = config.value.replace(_fkValue, globalValue);
  355. }
  356. }, this);
  357. }
  358. if (fkValue = config.name.match(/<(foreignKey.*?)>/g)) {
  359. fkValue.forEach(function (_fkValue) {
  360. var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
  361. if (uiConfig.someProperty('name', config.foreignKey[index])) {
  362. var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
  363. config.name = config.name.replace(_fkValue, globalValue);
  364. } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
  365. var globalValue;
  366. if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
  367. globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
  368. } else {
  369. globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
  370. }
  371. config.name = config.name.replace(_fkValue, globalValue);
  372. }
  373. }, this);
  374. }
  375. //For properties in the configMapping file having foreignKey and templateName properties.
  376. var templateValue = config.value.match(/<(templateName.*?)>/g);
  377. if (templateValue) {
  378. templateValue.forEach(function (_value) {
  379. var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
  380. if (this.get('globals').someProperty('name', config.templateName[index])) {
  381. var globalValue = this.get('globals').findProperty('name', config.templateName[index]).value;
  382. config.value = config.value.replace(_value, globalValue);
  383. } else {
  384. config.value = null;
  385. }
  386. }, this);
  387. }
  388. },
  389. /**
  390. * override site properties with the entered key-value pair in *-site.xml
  391. */
  392. setCustomConfigs: function () {
  393. var site = this.get('content.serviceConfigProperties').filterProperty('id', 'conf-site');
  394. site.forEach(function (_site) {
  395. var keyValue = _site.value.split(/\n+/);
  396. if (keyValue) {
  397. keyValue.forEach(function (_keyValue) {
  398. _keyValue = _keyValue.trim();
  399. console.log("The value of the keyValue is: " + _keyValue);
  400. // split on the first = encountered (the value may contain ='s)
  401. var matches = _keyValue.match(/^([^=]+)=(.*)$/);
  402. if (matches) {
  403. var key = matches[1];
  404. var value = matches[2];
  405. if (key) {
  406. this.setSiteProperty(key, value, _site.name + '.xml');
  407. }
  408. }
  409. }, this);
  410. }
  411. }, this);
  412. },
  413. /**
  414. * Set property of the site variable
  415. */
  416. setSiteProperty: function (key, value, filename) {
  417. this.get('configs').pushObject({
  418. "id": "site property",
  419. "name": key,
  420. "value": value,
  421. "filename": filename
  422. });
  423. },
  424. createGlobalSiteObj: function () {
  425. var globalSiteProperties = {};
  426. //this.get('globals').filterProperty('domain', 'global').forEach(function (_globalSiteObj) {
  427. this.get('globals').forEach(function (_globalSiteObj) {
  428. // do not pass any globals whose name ends with _host or _hosts
  429. if (!/_hosts?$/.test(_globalSiteObj.name)) {
  430. // append "m" to JVM memory options except for hadoop_heapsize
  431. if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && _globalSiteObj.name !== 'hadoop_heapsize') {
  432. globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value + "m";
  433. } else {
  434. globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value;
  435. }
  436. console.log("STEP8: name of the global property is: " + _globalSiteObj.name);
  437. console.log("STEP8: value of the global property is: " + _globalSiteObj.value);
  438. }
  439. }, this);
  440. return {"type": "global", "properties": globalSiteProperties};
  441. },
  442. createCoreSiteObj: function () {
  443. var serviceName = this.get('service.serviceName');
  444. var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml');
  445. var coreSiteProperties = {};
  446. // hadoop.proxyuser.oozie.hosts needs to be skipped if oozie is not selected
  447. var isOozieSelected = serviceName == 'OOZIE';
  448. var oozieUser = this.get('globals').someProperty('name', 'oozie_user') ? this.get('globals').findProperty('name', 'oozie_user').value : null;
  449. var isHiveSelected = serviceName == 'HIVE';
  450. var hiveUser = this.get('globals').someProperty('name', 'hive_user') ? this.get('globals').findProperty('name', 'hive_user').value : null;
  451. var isHcatSelected = serviceName == 'WEBHCAT';
  452. var hcatUser = this.get('globals').someProperty('name', 'hcat_user') ? this.get('globals').findProperty('name', 'hcat_user').value : null;
  453. coreSiteObj.forEach(function (_coreSiteObj) {
  454. if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
  455. coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value;
  456. }
  457. console.log("STEP*: name of the property is: " + _coreSiteObj.name);
  458. console.log("STEP8: value of the property is: " + _coreSiteObj.value);
  459. }, this);
  460. return {"type": "core-site", "properties": coreSiteProperties};
  461. },
  462. createHdfsSiteObj: function () {
  463. var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml');
  464. var hdfsProperties = {};
  465. hdfsSiteObj.forEach(function (_configProperty) {
  466. hdfsProperties[_configProperty.name] = _configProperty.value;
  467. console.log("STEP*: name of the property is: " + _configProperty.name);
  468. console.log("STEP8: value of the property is: " + _configProperty.value);
  469. }, this);
  470. return {"type": "hdfs-site", "properties": hdfsProperties };
  471. },
  472. createMrSiteObj: function () {
  473. var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml');
  474. var mrProperties = {};
  475. configs.forEach(function (_configProperty) {
  476. mrProperties[_configProperty.name] = _configProperty.value;
  477. console.log("STEP*: name of the property is: " + _configProperty.name);
  478. console.log("STEP8: value of the property is: " + _configProperty.value);
  479. }, this);
  480. return {type: 'mapred-site', properties: mrProperties};
  481. },
  482. createHbaseSiteObj: function () {
  483. var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml');
  484. var hbaseProperties = {};
  485. configs.forEach(function (_configProperty) {
  486. hbaseProperties[_configProperty.name] = _configProperty.value;
  487. }, this);
  488. return {type: 'hbase-site', properties: hbaseProperties};
  489. },
  490. createOozieSiteObj: function () {
  491. var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml');
  492. var oozieProperties = {};
  493. configs.forEach(function (_configProperty) {
  494. oozieProperties[_configProperty.name] = _configProperty.value;
  495. }, this);
  496. return {type: 'oozie-site', properties: oozieProperties};
  497. },
  498. createHiveSiteObj: function () {
  499. var configs = this.get('configs').filterProperty('filename', 'hive-site.xml');
  500. var hiveProperties = {};
  501. configs.forEach(function (_configProperty) {
  502. hiveProperties[_configProperty.name] = _configProperty.value;
  503. }, this);
  504. return {type: 'hive-site', properties: hiveProperties};
  505. },
  506. createWebHCatSiteObj: function () {
  507. var configs = this.get('configs').filterProperty('filename', 'webhcat-site.xml');
  508. var webHCatProperties = {};
  509. configs.forEach(function (_configProperty) {
  510. webHCatProperties[_configProperty.name] = _configProperty.value;
  511. }, this);
  512. return {type: 'webhcat-site', properties: webHCatProperties};
  513. },
  514. applyConfigs: function () {
  515. var self = this;
  516. var configTags;
  517. var clusterName = this.get('content.cluster.name');
  518. var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + this.get('service.serviceName');
  519. $.ajax({
  520. type: 'GET',
  521. url: url,
  522. async: false,
  523. timeout: 10000,
  524. dataType: 'text',
  525. success: function (data) {
  526. var jsonData = jQuery.parseJSON(data);
  527. configTags = jsonData.ServiceInfo.desired_configs;
  528. },
  529. error: function () {
  530. self.setTasksStatus(3, 'FAILED');
  531. },
  532. statusCode: require('data/statusCodes')
  533. });
  534. if (!configTags) {
  535. this.setTasksStatus(0, 'FAILED');
  536. return;
  537. }
  538. for (var tag in configTags) {
  539. if (this.get('createdConfigs').contains(tag)) {
  540. configTags[tag] = this.get('newConfigsTag');
  541. }
  542. }
  543. var data = {config: configTags};
  544. $.ajax({
  545. type: 'PUT',
  546. url: url,
  547. dataType: 'text',
  548. data: JSON.stringify(data),
  549. timeout: 5000,
  550. beforeSend: function () {
  551. self.setTasksStatus(3, 'PENDING');
  552. },
  553. success: function () {
  554. self.setTasksStatus(3, 'COMPLETED');
  555. },
  556. error: function () {
  557. self.setTasksStatus(3, 'FAILED');
  558. },
  559. statusCode: require('data/statusCodes')
  560. });
  561. },
  562. putInMaintenanceMode: function () {
  563. //todo after API providing
  564. this.setTasksStatus(4, 'COMPLETED');
  565. },
  566. installComponent: function () {
  567. var self = this;
  568. var clusterName = this.get('content.cluster.name');
  569. var url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INIT';
  570. var data = '{"HostRoles": {"state": "INSTALLED"}}';
  571. var method = 'PUT';
  572. $.ajax({
  573. type: method,
  574. url: url,
  575. data: data,
  576. dataType: 'text',
  577. timeout: App.timeout,
  578. beforeSend: function () {
  579. self.setTasksStatus(5, 'PENDING');
  580. },
  581. success: function (data) {
  582. if (jQuery.parseJSON(data)) {
  583. self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
  584. self.getLogsByRequest();
  585. } else {
  586. self.setTasksStatus(5, 'FAILED');
  587. }
  588. },
  589. error: function () {
  590. self.setTasksStatus(5, 'FAILED');
  591. },
  592. statusCode: require('data/statusCodes')
  593. });
  594. },
  595. startComponents: function () {
  596. var self = this;
  597. var clusterName = this.get('content.cluster.name');
  598. var serviceName = this.get('masterComponent.service_id');
  599. var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
  600. var data = '{"ServiceInfo": {"state": "STARTED"}}';
  601. var method = 'PUT';
  602. $.ajax({
  603. type: method,
  604. url: url,
  605. data: data,
  606. dataType: 'text',
  607. timeout: App.timeout,
  608. beforeSend: function () {
  609. self.setTasksStatus(6, 'PENDING');
  610. },
  611. success: function (data) {
  612. if (jQuery.parseJSON(data)) {
  613. self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
  614. self.getLogsByRequest();
  615. }
  616. },
  617. error: function () {
  618. self.setTasksStatus(6, 'FAILED');
  619. },
  620. statusCode: require('data/statusCodes')
  621. });
  622. },
  623. /**
  624. * Parse logs to define status of Start, Stop ot Install task
  625. * @param logs
  626. */
  627. parseLogs: function (logs) {
  628. var self = this;
  629. var task;
  630. var stopPolling = false;
  631. var starting = false;
  632. var polledData = logs.tasks;
  633. var status;
  634. if ((this.get('tasks')[5].status != 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED' && this.get('tasks')[0].status != 'COMPLETED') ||
  635. ((this.get('tasks')[5].status == 'COMPLETED') && this.get('tasks')[0].status == 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED')) {
  636. //stopping or starting components
  637. if (this.get('tasks')[0].status == 'COMPLETED') {
  638. task = 6;
  639. starting = true;
  640. } else {
  641. task = 0;
  642. }
  643. if (!polledData.someProperty('Tasks.status', 'PENDING') && !polledData.someProperty('Tasks.status', 'QUEUED') && !polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
  644. if (polledData.someProperty('Tasks.status', 'FAILED')) {
  645. this.setTasksStatus(task, 'FAILED');
  646. status = 'FAILED'
  647. } else {
  648. this.setTasksStatus(task, 'COMPLETED');
  649. status = 'COMPLETED';
  650. }
  651. stopPolling = true;
  652. } else if (polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
  653. var progress = polledData.filterProperty('Tasks.status', 'COMPLETED').length / polledData.length * 100;
  654. this.setTasksStatus(task, 'IN_PROGRESS');
  655. this.get('tasks')[task].set('progress', Math.round(progress));
  656. }
  657. } else {
  658. //installing component
  659. status = polledData[0].Tasks.status;
  660. this.setTasksStatus(5, status);
  661. if (status == 'IN_PROGRESS') {
  662. this.get('tasks')[5].set('progress', '50');
  663. }
  664. if (status == 'COMPLETED' || status == 'FAILED') {
  665. stopPolling = true;
  666. }
  667. }
  668. if (!stopPolling) {
  669. window.setTimeout(function () {
  670. self.getLogsByRequest()
  671. }, self.POLL_INTERVAL);
  672. } else {
  673. if (status == 'FAILED') {
  674. //todo show retry
  675. }
  676. if (starting && status == 'COMPLETED') {
  677. this.set('isSubmitDisabled', false);
  678. }
  679. }
  680. },
  681. POLL_INTERVAL: 4000,
  682. getLogsByRequest: function () {
  683. var self = this;
  684. var clusterName = this.get('content.cluster.name');
  685. var requestId = this.get('currentRequestId');
  686. var url = App.apiPrefix + '/clusters/' + clusterName + '/requests/' + requestId + '?fields=tasks/*';
  687. $.ajax({
  688. type: 'GET',
  689. url: url,
  690. timeout: App.timeout,
  691. dataType: 'text',
  692. success: function (data) {
  693. self.parseLogs(jQuery.parseJSON(data));
  694. },
  695. error: function () {
  696. this.set('status', 'FAILED');
  697. },
  698. statusCode: require('data/statusCodes')
  699. }).retry({times: App.maxRetries, timeout: App.timeout}).then(null,
  700. function () {
  701. App.showReloadPopup();
  702. console.log('Install services all retries FAILED');
  703. }
  704. );
  705. },
  706. removeComponent: function () {
  707. //todo after API providing
  708. this.setTasksStatus(7, 'COMPLETED');
  709. },
  710. submit: function () {
  711. if (!this.get('isSubmitDisabled')) {
  712. App.router.send('next');
  713. }
  714. }
  715. })