add_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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. return this._super().filter(function(component){
  182. return component.isInstalled;
  183. });
  184. },
  185. /**
  186. * Load master component hosts data for using in required step controllers
  187. */
  188. loadSlaveComponentHosts: function () {
  189. var slaveComponentHosts = this.getDBProperty('slaveComponentHosts');
  190. if (!slaveComponentHosts) {
  191. slaveComponentHosts = this.getSlaveComponentHosts();
  192. }
  193. this.set("content.slaveComponentHosts", slaveComponentHosts);
  194. console.log("AddHostController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
  195. },
  196. /**
  197. * Load information about hosts with clients components
  198. */
  199. loadClients: function () {
  200. var clients = this.getDBProperty('clientInfo');
  201. this.set('content.clients', clients);
  202. console.log("AddHostController.loadClients: loaded list ", clients);
  203. },
  204. /**
  205. * Generate clients list for selected services and save it to model
  206. */
  207. saveClients: function () {
  208. var clients = [];
  209. var serviceComponents = require('data/service_components');
  210. var hostComponents = App.HostComponent.find();
  211. this.get('content.services').filterProperty('isSelected', true).forEach(function (_service) {
  212. var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
  213. if (client) {
  214. clients.pushObject({
  215. component_name: client.component_name,
  216. display_name: client.display_name,
  217. isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0
  218. });
  219. }
  220. }, this);
  221. this.setDBProperty('clientInfo', clients);
  222. this.set('content.clients', clients);
  223. console.log("AddHostController.saveClients: saved list ", clients);
  224. },
  225. /**
  226. * Apply config groups from step4 Configurations
  227. */
  228. applyConfigGroup: function () {
  229. var serviceConfigGroups = this.get('content.serviceConfigGroups');
  230. serviceConfigGroups.forEach(function (group){
  231. if (group.configGroups.someProperty('ConfigGroup.group_name', group.selectedConfigGroup)) {
  232. var configGroup = group.configGroups.findProperty('ConfigGroup.group_name', group.selectedConfigGroup);
  233. group.hosts.forEach(function(host){
  234. configGroup.ConfigGroup.hosts.push({
  235. host_name: host
  236. });
  237. },this);
  238. delete configGroup.href;
  239. App.ajax.send({
  240. name: 'config_groups.update_config_group',
  241. sender: this,
  242. data: {
  243. id: configGroup.ConfigGroup.id,
  244. configGroup: configGroup
  245. }
  246. });
  247. }
  248. },this);
  249. },
  250. /**
  251. * Load information about selected config groups
  252. */
  253. getServiceConfigGroups: function () {
  254. var serviceConfigGroups = this.getDBProperty('serviceConfigGroups');
  255. this.set('content.serviceConfigGroups', serviceConfigGroups);
  256. },
  257. /**
  258. * Save information about selected config groups
  259. */
  260. saveServiceConfigGroups: function () {
  261. this.setDBProperty('serviceConfigGroups', this.get('content.serviceConfigGroups'));
  262. this.set('content.serviceConfigGroups', this.get('content.serviceConfigGroups'));
  263. },
  264. /**
  265. * Set content.serviceConfigGroups for step4
  266. */
  267. loadServiceConfigGroups: function () {
  268. var slaveComponentHosts = this.get('content.slaveComponentHosts');
  269. var selectedServices = [];
  270. var selectedClientHosts = slaveComponentHosts.findProperty('componentName', 'CLIENT').hosts.mapProperty('hostName');
  271. var componentServiceMap = App.QuickDataMapper.componentServiceMap();
  272. slaveComponentHosts.forEach(function (slave) {
  273. if (slave.hosts.length > 0) {
  274. if (slave.componentName != "CLIENT") {
  275. var service = componentServiceMap[slave.componentName];
  276. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  277. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name');
  278. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  279. configGroupsNames.unshift(defaultGroupName);
  280. selectedServices.push({
  281. serviceId: service,
  282. displayName: App.Service.DisplayNames[service],
  283. hosts: slave.hosts.mapProperty('hostName'),
  284. configGroupsNames: configGroupsNames,
  285. configGroups: configGroups,
  286. selectedConfigGroup: defaultGroupName
  287. });
  288. }
  289. }
  290. }, this);
  291. if (selectedClientHosts.length > 0) {
  292. this.loadClients();
  293. var clients = this.get('content.clients');
  294. clients.forEach(function (client) {
  295. var service = componentServiceMap[client.component_name];
  296. var serviceMatch = selectedServices.findProperty('serviceId', service);
  297. if (serviceMatch) {
  298. serviceMatch.hosts = serviceMatch.hosts.concat(selectedClientHosts).uniq();
  299. } else {
  300. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  301. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name').sort();
  302. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  303. configGroupsNames.unshift(defaultGroupName);
  304. selectedServices.push({
  305. serviceId: service,
  306. displayName: App.Service.DisplayNames[service],
  307. hosts: selectedClientHosts,
  308. configGroupsNames: configGroupsNames,
  309. configGroups: configGroups,
  310. selectedConfigGroup: defaultGroupName
  311. });
  312. }
  313. }, this);
  314. }
  315. selectedServices.forEach(function(selectedService){
  316. selectedService.configGroups.sort(function(cfgA, cfgB){
  317. return cfgA.ConfigGroup.group_name >= cfgB.ConfigGroup.group_name;
  318. });
  319. });
  320. this.set('content.serviceConfigGroups', selectedServices);
  321. },
  322. loadServiceConfigProperties: function () {
  323. var serviceConfigProperties = App.db.get('AddService', 'serviceConfigProperties');
  324. if (!serviceConfigProperties || !serviceConfigProperties.length) {
  325. serviceConfigProperties = App.db.get('Installer', 'serviceConfigProperties');
  326. }
  327. this.set('content.serviceConfigProperties', serviceConfigProperties);
  328. console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
  329. },
  330. /**
  331. * Load data for all steps until <code>current step</code>
  332. */
  333. loadAllPriorSteps: function () {
  334. var step = this.get('currentStep');
  335. switch (step) {
  336. case '7':
  337. case '6':
  338. case '5':
  339. this.loadServiceConfigProperties();
  340. this.getServiceConfigGroups();
  341. case '4':
  342. case '3':
  343. this.loadClients();
  344. this.loadServices();
  345. this.loadMasterComponentHosts();
  346. this.loadSlaveComponentHosts();
  347. this.load('hosts');
  348. case '2':
  349. this.loadServices();
  350. case '1':
  351. this.load('hosts');
  352. this.load('installOptions');
  353. this.load('cluster');
  354. }
  355. },
  356. /**
  357. * Remove all loaded data.
  358. * Created as copy for App.router.clearAllSteps
  359. */
  360. clearAllSteps: function () {
  361. this.clearInstallOptions();
  362. // clear temporary information stored during the install
  363. this.set('content.cluster', this.getCluster());
  364. },
  365. /**
  366. * Clear all temporary data
  367. */
  368. finish: function () {
  369. this.setCurrentStep('1');
  370. this.clearAllSteps();
  371. this.clearStorageData();
  372. App.router.get('updateController').updateAll();
  373. App.updater.immediateRun('updateHost');
  374. },
  375. installServices: function (isRetry) {
  376. this.set('content.cluster.oldRequestsId', []);
  377. var clusterName = this.get('content.cluster.name');
  378. var data;
  379. var name;
  380. var hostnames = [];
  381. for (var hostname in this.getDBProperty('hosts')) {
  382. hostnames.push(hostname);
  383. }
  384. if (isRetry) {
  385. name = 'wizard.install_services.add_host_controller.is_retry';
  386. }
  387. else {
  388. name = 'wizard.install_services.add_host_controller.not_is_retry';
  389. }
  390. data = {
  391. "RequestInfo": {
  392. "context": Em.I18n.t('requestInfo.installComponents'),
  393. "query": "HostRoles/host_name.in(" + hostnames.join(',') + ")"
  394. },
  395. "Body": {
  396. "HostRoles": {"state": "INSTALLED"}
  397. }
  398. };
  399. data = JSON.stringify(data);
  400. App.ajax.send({
  401. name: name,
  402. sender: this,
  403. data: {
  404. data: data,
  405. cluster: clusterName
  406. },
  407. success: 'installServicesSuccessCallback',
  408. error: 'installServicesErrorCallback'
  409. });
  410. }
  411. });