add_controller.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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.AddHostController = App.WizardController.extend({
  20. name: 'addHostController',
  21. totalSteps: 7,
  22. /**
  23. * Used for hiding back button in wizard
  24. */
  25. hideBackButton: true,
  26. /**
  27. * All wizards data will be stored in this variable
  28. *
  29. * cluster - cluster name
  30. * hosts - hosts, ssh key, repo info, etc.
  31. * services - services list
  32. * hostsInfo - list of selected hosts
  33. * slaveComponentHosts, hostSlaveComponents - info about slave hosts
  34. * masterComponentHosts - info about master hosts
  35. * serviceConfigGroups - info about selected config group for service
  36. * configGroups - all config groups
  37. * config??? - to be described later
  38. */
  39. content: Em.Object.create({
  40. cluster: null,
  41. hosts: null,
  42. installOptions: null,
  43. services: null,
  44. slaveComponentHosts: null,
  45. masterComponentHosts: null,
  46. serviceConfigProperties: null,
  47. advancedServiceConfig: null,
  48. controllerName: 'addHostController',
  49. serviceConfigGroups: null,
  50. configGroups: null
  51. }),
  52. components:require('data/service_components'),
  53. setCurrentStep: function (currentStep, completed) {
  54. this._super(currentStep, completed);
  55. App.clusterStatus.setClusterStatus({
  56. wizardControllerName: this.get('name'),
  57. localdb: App.db.data
  58. });
  59. },
  60. /**
  61. * return new object extended from clusterStatusTemplate
  62. * @return Object
  63. */
  64. getCluster: function(){
  65. return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
  66. },
  67. /**
  68. * return new object extended from installOptionsTemplate
  69. * @return Object
  70. */
  71. getInstallOptions: function(){
  72. return jQuery.extend({}, this.get('installOptionsTemplate'));
  73. },
  74. /**
  75. * return empty hosts array
  76. * @return Array
  77. */
  78. getHosts: function(){
  79. return [];
  80. },
  81. /**
  82. * Remove host from model. Used at <code>Confirm hosts</code> step
  83. * @param hosts Array of hosts, which we want to delete
  84. */
  85. removeHosts: function (hosts) {
  86. var dbHosts = this.getDBProperty('hosts');
  87. hosts.forEach(function (_hostInfo) {
  88. var host = _hostInfo.hostName;
  89. delete dbHosts[host];
  90. });
  91. this.setDBProperty('hosts', dbHosts);
  92. },
  93. /**
  94. * Load services data from server.
  95. */
  96. loadServicesFromServer: function() {
  97. var displayOrderConfig = require('data/services');
  98. var apiUrl = App.get('stack2VersionURL');
  99. var apiService = this.loadServiceComponents(displayOrderConfig, apiUrl);
  100. //
  101. apiService.forEach(function(item, index){
  102. apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
  103. apiService[index].isDisabled = apiService[index].isSelected;
  104. apiService[index].isInstalled = apiService[index].isSelected;
  105. });
  106. this.set('content.services', apiService);
  107. this.setDBProperty('service', apiService);
  108. },
  109. /**
  110. * Load services data. Will be used at <code>Select services(step4)</code> step
  111. */
  112. loadServices: function () {
  113. var servicesInfo = this.getDBProperty('service');
  114. servicesInfo.forEach(function (item, index) {
  115. servicesInfo[index] = Em.Object.create(item);
  116. });
  117. this.set('content.services', servicesInfo);
  118. console.log('AddHostController.loadServices: loaded data ', servicesInfo);
  119. var serviceNames = servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName');
  120. console.log('selected services ', serviceNames);
  121. },
  122. /**
  123. * Load master component hosts data for using in required step controllers
  124. */
  125. loadMasterComponentHosts: function () {
  126. var masterComponentHosts = this.getDBProperty('masterComponentHosts');
  127. if (!masterComponentHosts) {
  128. masterComponentHosts = [];
  129. App.HostComponent.find().filterProperty('isMaster', true).forEach(function (item) {
  130. masterComponentHosts.push({
  131. component: item.get('componentName'),
  132. hostName: item.get('host.hostName'),
  133. isInstalled: true,
  134. serviceId: item.get('service.id'),
  135. display_name: item.get('displayName')
  136. })
  137. });
  138. this.setDBProperty('masterComponentHosts', masterComponentHosts);
  139. }
  140. this.set("content.masterComponentHosts", masterComponentHosts);
  141. console.log("AddHostController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
  142. },
  143. /**
  144. * Save HBase and ZooKeeper to main controller
  145. * @param stepController
  146. */
  147. saveHbZk: function(stepController) {
  148. var self = this;
  149. var hosts = stepController.get('hosts');
  150. var headers = stepController.get('headers');
  151. var masterComponentHosts = this.getDBProperty('masterComponentHosts');
  152. headers.forEach(function(header) {
  153. var rm = masterComponentHosts.filterProperty('component', header.get('name'));
  154. if(rm) {
  155. masterComponentHosts.removeObjects(rm);
  156. }
  157. });
  158. headers.forEach(function(header) {
  159. var component = self.get('components').findProperty('component_name', header.get('name'));
  160. hosts.forEach(function(host) {
  161. if (host.get('checkboxes').findProperty('title', component.display_name).checked) {
  162. masterComponentHosts .push({
  163. display_name: component.display_name,
  164. component: component.component_name,
  165. hostName: host.get('hostName'),
  166. serviceId: component.service_name,
  167. isInstalled: false
  168. });
  169. }
  170. });
  171. });
  172. console.log("installerController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
  173. this.setDBProperty('masterComponentHosts', masterComponentHosts);
  174. this.set('content.masterComponentHosts', masterComponentHosts);
  175. },
  176. /**
  177. * return slaveComponents bound to hosts
  178. * @return {Array}
  179. */
  180. getSlaveComponentHosts: function () {
  181. var components = [
  182. {
  183. name: 'DATANODE',
  184. service: 'HDFS'
  185. },
  186. {
  187. name: 'TASKTRACKER',
  188. service: 'MAPREDUCE'
  189. },
  190. {
  191. name: 'HBASE_REGIONSERVER',
  192. service: 'HBASE'
  193. }
  194. ];
  195. var result = [];
  196. var services = App.Service.find();
  197. var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
  198. for (var index = 0; index < components.length; index++) {
  199. var comp = components[index];
  200. if (!selectedServices.contains(comp.service)) {
  201. continue;
  202. }
  203. var service = services.findProperty('id', comp.service);
  204. var hosts = [];
  205. service.get('hostComponents').filterProperty('componentName', comp.name).forEach(function (host_component) {
  206. hosts.push({
  207. group: "Default",
  208. hostName: host_component.get('host.id'),
  209. isInstalled: true
  210. });
  211. }, this);
  212. result.push({
  213. componentName: comp.name,
  214. displayName: App.format.role(comp.name),
  215. hosts: hosts,
  216. isInstalled: true
  217. })
  218. }
  219. var clientsHosts = App.HostComponent.find().filterProperty('componentName', 'HDFS_CLIENT');
  220. var hosts = [];
  221. clientsHosts.forEach(function (host_component) {
  222. hosts.push({
  223. group: "Default",
  224. hostName: host_component.get('host.id'),
  225. isInstalled: true
  226. });
  227. }, this);
  228. result.push({
  229. componentName: 'CLIENT',
  230. displayName: 'client',
  231. hosts: hosts,
  232. isInstalled: true
  233. });
  234. return result;
  235. },
  236. /**
  237. * Load master component hosts data for using in required step controllers
  238. */
  239. loadSlaveComponentHosts: function () {
  240. var slaveComponentHosts = this.getDBProperty('slaveComponentHosts');
  241. if (!slaveComponentHosts) {
  242. slaveComponentHosts = this.getSlaveComponentHosts();
  243. }
  244. this.set("content.slaveComponentHosts", slaveComponentHosts);
  245. console.log("AddHostController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
  246. },
  247. /**
  248. * Load information about hosts with clients components
  249. */
  250. loadClients: function () {
  251. var clients = this.getDBProperty('clientInfo');
  252. this.set('content.clients', clients);
  253. console.log("AddHostController.loadClients: loaded list ", clients);
  254. },
  255. /**
  256. * Generate clients list for selected services and save it to model
  257. * @param stepController step4WizardController
  258. */
  259. saveClients: function () {
  260. var clients = [];
  261. var serviceComponents = require('data/service_components');
  262. var hostComponents = App.HostComponent.find();
  263. this.get('content.services').filterProperty('isSelected', true).forEach(function (_service) {
  264. var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
  265. if (client) {
  266. clients.pushObject({
  267. component_name: client.component_name,
  268. display_name: client.display_name,
  269. isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0
  270. });
  271. }
  272. }, this);
  273. this.setDBProperty('clientInfo', clients);
  274. this.set('content.clients', clients);
  275. console.log("AddHostController.saveClients: saved list ", clients);
  276. },
  277. /**
  278. * Apply config groups from step4 Configurations
  279. */
  280. applyConfigGroup: function () {
  281. var serviceConfigGroups = this.get('content.serviceConfigGroups');
  282. serviceConfigGroups.forEach(function (group){
  283. if(group.selectedConfigGroup != "Default") {
  284. var configGroup = group.configGroups.findProperty('ConfigGroup.group_name', group.selectedConfigGroup);
  285. group.hosts.forEach(function(host){
  286. configGroup.ConfigGroup.hosts.push({
  287. host_name: host
  288. });
  289. },this);
  290. delete configGroup.href;
  291. App.ajax.send({
  292. name: 'config_groups.update_config_group',
  293. sender: this,
  294. data: {
  295. id: configGroup.ConfigGroup.id,
  296. configGroup: configGroup
  297. }
  298. });
  299. }
  300. },this);
  301. },
  302. /**
  303. * Load information about selected config groups
  304. */
  305. getServiceConfigGroups: function () {
  306. var serviceConfigGroups = this.getDBProperty('serviceConfigGroups');
  307. this.set('content.serviceConfigGroups', serviceConfigGroups);
  308. },
  309. /**
  310. * Save information about selected config groups
  311. */
  312. saveServiceConfigGroups: function () {
  313. this.setDBProperty('serviceConfigGroups', this.get('content.serviceConfigGroups'));
  314. this.set('content.serviceConfigGroups', this.get('content.serviceConfigGroups'));
  315. },
  316. /**
  317. * Set content.serviceConfigGroups for step4
  318. */
  319. loadServiceConfigGroups: function () {
  320. var slaveComponentHosts = this.get('content.slaveComponentHosts');
  321. var selectedServices = [];
  322. var selectedClientHosts = slaveComponentHosts.findProperty('componentName', 'CLIENT').hosts.mapProperty('hostName');
  323. var componentServiceMap = App.QuickDataMapper.componentServiceMap;
  324. slaveComponentHosts.forEach(function (slave) {
  325. if (slave.hosts.length > 0) {
  326. if (slave.componentName != "CLIENT") {
  327. var service = componentServiceMap[slave.componentName];
  328. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  329. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name');
  330. configGroupsNames.unshift('Default');
  331. selectedServices.push({
  332. serviceId: service,
  333. displayName: App.Service.DisplayNames[service],
  334. hosts: slave.hosts.mapProperty('hostName'),
  335. configGroupsNames: configGroupsNames,
  336. configGroups: configGroups,
  337. selectedConfigGroup: "Default"
  338. });
  339. }
  340. }
  341. }, this);
  342. if (selectedClientHosts.length > 0) {
  343. this.loadClients();
  344. var clients = this.get('content.clients');
  345. clients.forEach(function (client) {
  346. var service = componentServiceMap[client.component_name];
  347. var serviceMatch = selectedServices.findProperty('serviceId', service);
  348. if (serviceMatch) {
  349. serviceMatch.hosts = serviceMatch.hosts.concat(selectedClientHosts).uniq();
  350. } else {
  351. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  352. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name').sort();
  353. configGroupsNames.unshift('Default');
  354. selectedServices.push({
  355. serviceId: service,
  356. displayName: App.Service.DisplayNames[service],
  357. hosts: selectedClientHosts,
  358. configGroupsNames: configGroupsNames,
  359. configGroups: configGroups,
  360. selectedConfigGroup: "Default"
  361. });
  362. }
  363. }, this);
  364. }
  365. selectedServices.forEach(function(selectedService){
  366. selectedService.configGroups.sort(function(cfgA, cfgB){
  367. return cfgA.ConfigGroup.group_name >= cfgB.ConfigGroup.group_name;
  368. });
  369. });
  370. this.set('content.serviceConfigGroups', selectedServices);
  371. },
  372. /**
  373. * Load data for all steps until <code>current step</code>
  374. */
  375. loadAllPriorSteps: function () {
  376. var step = this.get('currentStep');
  377. switch (step) {
  378. case '7':
  379. case '6':
  380. case '5':
  381. this.loadServiceConfigProperties();
  382. this.getServiceConfigGroups();
  383. case '4':
  384. case '3':
  385. this.loadClients();
  386. this.loadServices();
  387. this.loadMasterComponentHosts();
  388. this.loadSlaveComponentHosts();
  389. this.load('hosts');
  390. case '2':
  391. this.loadServices();
  392. case '1':
  393. this.load('hosts');
  394. this.load('installOptions');
  395. this.load('cluster');
  396. }
  397. },
  398. /**
  399. * Remove all loaded data.
  400. * Created as copy for App.router.clearAllSteps
  401. */
  402. clearAllSteps: function () {
  403. this.clearInstallOptions();
  404. // clear temporary information stored during the install
  405. this.set('content.cluster', this.getCluster());
  406. },
  407. /**
  408. * Clear all temporary data
  409. */
  410. finish: function () {
  411. this.setCurrentStep('1');
  412. this.clearAllSteps();
  413. this.clearStorageData();
  414. App.router.get('updateController').updateAll();
  415. App.updater.immediateRun('updateHost');
  416. },
  417. installServices: function (isRetry) {
  418. this.set('content.cluster.oldRequestsId', []);
  419. var clusterName = this.get('content.cluster.name');
  420. var data;
  421. var name;
  422. var hostnames = [];
  423. for (var hostname in this.getDBProperty('hosts')) {
  424. hostnames.push(hostname);
  425. }
  426. if (isRetry) {
  427. name = 'wizard.install_services.add_host_controller.is_retry';
  428. }
  429. else {
  430. name = 'wizard.install_services.add_host_controller.not_is_retry';
  431. }
  432. data = {
  433. "RequestInfo": {
  434. "context": Em.I18n.t('requestInfo.installComponents'),
  435. "query": "HostRoles/host_name.in(" + hostnames.join(',') + ")"
  436. },
  437. "Body": {
  438. "HostRoles": {"state": "INSTALLED"}
  439. }
  440. };
  441. data = JSON.stringify(data);
  442. App.ajax.send({
  443. name: name,
  444. sender: this,
  445. data: {
  446. data: data,
  447. cluster: clusterName
  448. },
  449. success: 'installServicesSuccessCallback',
  450. error: 'installServicesErrorCallback'
  451. });
  452. }
  453. });