add_controller.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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. */
  258. saveClients: function () {
  259. var clients = [];
  260. var serviceComponents = require('data/service_components');
  261. var hostComponents = App.HostComponent.find();
  262. this.get('content.services').filterProperty('isSelected', true).forEach(function (_service) {
  263. var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
  264. if (client) {
  265. clients.pushObject({
  266. component_name: client.component_name,
  267. display_name: client.display_name,
  268. isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0
  269. });
  270. }
  271. }, this);
  272. this.setDBProperty('clientInfo', clients);
  273. this.set('content.clients', clients);
  274. console.log("AddHostController.saveClients: saved list ", clients);
  275. },
  276. /**
  277. * Apply config groups from step4 Configurations
  278. */
  279. applyConfigGroup: function () {
  280. var serviceConfigGroups = this.get('content.serviceConfigGroups');
  281. serviceConfigGroups.forEach(function (group){
  282. if (group.configGroups.someProperty('ConfigGroup.group_name', group.selectedConfigGroup)) {
  283. var configGroup = group.configGroups.findProperty('ConfigGroup.group_name', group.selectedConfigGroup);
  284. group.hosts.forEach(function(host){
  285. configGroup.ConfigGroup.hosts.push({
  286. host_name: host
  287. });
  288. },this);
  289. delete configGroup.href;
  290. App.ajax.send({
  291. name: 'config_groups.update_config_group',
  292. sender: this,
  293. data: {
  294. id: configGroup.ConfigGroup.id,
  295. configGroup: configGroup
  296. }
  297. });
  298. }
  299. },this);
  300. },
  301. /**
  302. * Load information about selected config groups
  303. */
  304. getServiceConfigGroups: function () {
  305. var serviceConfigGroups = this.getDBProperty('serviceConfigGroups');
  306. this.set('content.serviceConfigGroups', serviceConfigGroups);
  307. },
  308. /**
  309. * Save information about selected config groups
  310. */
  311. saveServiceConfigGroups: function () {
  312. this.setDBProperty('serviceConfigGroups', this.get('content.serviceConfigGroups'));
  313. this.set('content.serviceConfigGroups', this.get('content.serviceConfigGroups'));
  314. },
  315. /**
  316. * Set content.serviceConfigGroups for step4
  317. */
  318. loadServiceConfigGroups: function () {
  319. var slaveComponentHosts = this.get('content.slaveComponentHosts');
  320. var selectedServices = [];
  321. var selectedClientHosts = slaveComponentHosts.findProperty('componentName', 'CLIENT').hosts.mapProperty('hostName');
  322. var componentServiceMap = App.QuickDataMapper.componentServiceMap();
  323. slaveComponentHosts.forEach(function (slave) {
  324. if (slave.hosts.length > 0) {
  325. if (slave.componentName != "CLIENT") {
  326. var service = componentServiceMap[slave.componentName];
  327. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  328. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name');
  329. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  330. configGroupsNames.unshift(defaultGroupName);
  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: defaultGroupName
  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. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  354. configGroupsNames.unshift(defaultGroupName);
  355. selectedServices.push({
  356. serviceId: service,
  357. displayName: App.Service.DisplayNames[service],
  358. hosts: selectedClientHosts,
  359. configGroupsNames: configGroupsNames,
  360. configGroups: configGroups,
  361. selectedConfigGroup: defaultGroupName
  362. });
  363. }
  364. }, this);
  365. }
  366. selectedServices.forEach(function(selectedService){
  367. selectedService.configGroups.sort(function(cfgA, cfgB){
  368. return cfgA.ConfigGroup.group_name >= cfgB.ConfigGroup.group_name;
  369. });
  370. });
  371. this.set('content.serviceConfigGroups', selectedServices);
  372. },
  373. /**
  374. * Load data for all steps until <code>current step</code>
  375. */
  376. loadAllPriorSteps: function () {
  377. var step = this.get('currentStep');
  378. switch (step) {
  379. case '7':
  380. case '6':
  381. case '5':
  382. this.loadServiceConfigProperties();
  383. this.getServiceConfigGroups();
  384. case '4':
  385. case '3':
  386. this.loadClients();
  387. this.loadServices();
  388. this.loadMasterComponentHosts();
  389. this.loadSlaveComponentHosts();
  390. this.load('hosts');
  391. case '2':
  392. this.loadServices();
  393. case '1':
  394. this.load('hosts');
  395. this.load('installOptions');
  396. this.load('cluster');
  397. }
  398. },
  399. /**
  400. * Remove all loaded data.
  401. * Created as copy for App.router.clearAllSteps
  402. */
  403. clearAllSteps: function () {
  404. this.clearInstallOptions();
  405. // clear temporary information stored during the install
  406. this.set('content.cluster', this.getCluster());
  407. },
  408. /**
  409. * Clear all temporary data
  410. */
  411. finish: function () {
  412. this.setCurrentStep('1');
  413. this.clearAllSteps();
  414. this.clearStorageData();
  415. App.router.get('updateController').updateAll();
  416. App.updater.immediateRun('updateHost');
  417. },
  418. installServices: function (isRetry) {
  419. this.set('content.cluster.oldRequestsId', []);
  420. var clusterName = this.get('content.cluster.name');
  421. var data;
  422. var name;
  423. var hostnames = [];
  424. for (var hostname in this.getDBProperty('hosts')) {
  425. hostnames.push(hostname);
  426. }
  427. if (isRetry) {
  428. name = 'wizard.install_services.add_host_controller.is_retry';
  429. }
  430. else {
  431. name = 'wizard.install_services.add_host_controller.not_is_retry';
  432. }
  433. data = {
  434. "RequestInfo": {
  435. "context": Em.I18n.t('requestInfo.installComponents'),
  436. "query": "HostRoles/host_name.in(" + hostnames.join(',') + ")"
  437. },
  438. "Body": {
  439. "HostRoles": {"state": "INSTALLED"}
  440. }
  441. };
  442. data = JSON.stringify(data);
  443. App.ajax.send({
  444. name: name,
  445. sender: this,
  446. data: {
  447. data: data,
  448. cluster: clusterName
  449. },
  450. success: 'installServicesSuccessCallback',
  451. error: 'installServicesErrorCallback'
  452. });
  453. }
  454. });