assignMasters.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. *
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. *
  20. */
  21. function AssignMasters() {
  22. var managerHostName;
  23. var allHosts;
  24. var masterServices;
  25. var hostsToMasterServices;
  26. function getNodeInfo(nodeName) {
  27. // Y.log("nodename: " + nodeName);
  28. if (nodeName == null) {
  29. return null;
  30. }
  31. for (var host in allHosts) {
  32. if (allHosts[host].hostName == nodeName) {
  33. // Y.log("Get node info: " + allHosts[host].hostName);
  34. return allHosts[host];
  35. }
  36. }
  37. return null;
  38. }
  39. function addCommasToInt(num) {
  40. return num.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
  41. }
  42. function getTotalMemForDisplay(totalMem) {
  43. return Math.round(totalMem / 102.4)/10 + "GB";
  44. }
  45. function renderHostsToMasterServices(hostsToMasterServices) {
  46. var markup = '';
  47. for (var host in hostsToMasterServices) {
  48. var hostInfo = getNodeInfo(host);
  49. markup += '<div class="hostToMasterServices"><h3>' + host + '<span class="hostInfo">' + getTotalMemForDisplay(hostInfo.totalMem) + ', ' + hostInfo.cpuCount + ' cores</span></h3><ul>';
  50. for (var j in hostsToMasterServices[host]) {
  51. if (j === "KERBEROS_SERVER" && Y.one("#useExistingKerberos").get('checked') === true) {
  52. continue;
  53. }
  54. markup += '<li>' + hostsToMasterServices[host][j] + '</li>';
  55. }
  56. markup += '</ul><div style="clear:both"></div></div>';
  57. }
  58. $('#hostsToMasterServices').html(markup);
  59. }
  60. function addMasterServiceToHost(masterName, hostName, hostsToMasterServices, masterServices) {
  61. // enforce constraints on what services can be co-hosted (unless those suggestions were made by the server initially)
  62. // we currently disallow:
  63. // 1. namenode and secondary namenode to be on the same host
  64. // 2. more than one zookeeper server to be on the same host
  65. if (hostsToMasterServices[hostName] != null) {
  66. for (var service in hostsToMasterServices[hostName]) {
  67. if (masterName == 'NAMENODE' && service == 'SNAMENODE' || masterName == 'SNAMENODE' && service == 'NAMENODE') {
  68. alert('NameNode and Secondary NameNode cannot be hosted on the same host.');
  69. return false;
  70. }
  71. if (masterName.indexOf('ZOOKEEPER') == 0 && service.indexOf('ZOOKEEPER') == 0) {
  72. alert('You cannot put more than one ZooKeeper Server on the same host.');
  73. return false;
  74. }
  75. }
  76. }
  77. if (hostsToMasterServices[hostName] == null) {
  78. hostsToMasterServices[hostName] = {};
  79. }
  80. hostsToMasterServices[hostName][masterName] = masterServices[masterName].displayName;
  81. return true;
  82. }
  83. function removeMasterServiceFromHost(masterName, hostName, hostsToMasterServices) {
  84. for (var i in hostsToMasterServices[hostName]) {
  85. if (i == masterName) {
  86. delete hostsToMasterServices[hostName][i];
  87. //alert(Object.keys(hostsToMasterServices[hostName]).length);
  88. if (Object.keys(hostsToMasterServices[hostName]).length == 0) {
  89. //alert('remove');
  90. delete hostsToMasterServices[hostName];
  91. }
  92. return;
  93. }
  94. }
  95. }
  96. function getHostInfoForDisplay(host) {
  97. return host.hostName + ' - ' + getTotalMemForDisplay(host.totalMem) + ', ' + host.cpuCount + ' cores';
  98. }
  99. function getMasterHostSelect(masterName, chosenHostName) {
  100. var chosenHost = getNodeInfo(chosenHostName);
  101. var markup = '<select name="' + masterName + '">';
  102. markup += '<option selected="selected" value="' + chosenHost.hostName + '">' + getHostInfoForDisplay(chosenHost) + '</option>';
  103. for (var i in allHosts) {
  104. var host = allHosts[i];
  105. if (host.hostName != chosenHost.hostName) {
  106. markup += '<option value="' + host.hostName + '">' + host.hostName + ' - ' + getTotalMemForDisplay(host.totalMem) + ', ' + host.cpuCount + ' cores</option>';
  107. }
  108. }
  109. markup += '</select><div style="clear:both"></div><input type="hidden" style="display:none" id="' + masterName + 'ChosenHost" value="' + chosenHost.hostName + '">';
  110. return markup;
  111. }
  112. function attachEventHandlers() {
  113. var submitButton = Y.one('#selectServiceMastersSubmitButtonId');
  114. submitButton.detach();
  115. submitButton.on('click', function (e) {
  116. Y.log('clicked select service submit');
  117. e.target.set('disabled', true);
  118. var assignHostsRequestData = {};
  119. for (var masterName in masterServices) {
  120. var hostName = $('select[name=' + masterName + ']').val();
  121. if (masterName.indexOf("ZOOKEEPER_SERVER") == 0) {
  122. if (assignHostsRequestData['ZOOKEEPER_SERVER'] == null) {
  123. assignHostsRequestData['ZOOKEEPER_SERVER'] = [];
  124. }
  125. assignHostsRequestData['ZOOKEEPER_SERVER'].push(hostName);
  126. } else {
  127. if (assignHostsRequestData[masterName] == null) {
  128. assignHostsRequestData[masterName] = [];
  129. }
  130. if (masterName === 'KERBEROS_SERVER') {
  131. var checked = Y.one("#useExistingKerberos").get('checked');
  132. if (checked) {
  133. App.props.securityType = "USER_SET_KERBEROS";
  134. hostName = Y.one("#existingKerberosHostname").get('value');
  135. } else {
  136. App.props.securityType = "AMBARI_SET_KERBEROS";
  137. }
  138. }
  139. assignHostsRequestData[masterName].push(hostName);
  140. }
  141. // Y.log("Assignment for " + masterName + " is " + assignHostsRequestData[masterName]);
  142. };
  143. Y.io("../php/frontend/assignMasters.php?clusterName=" + App.props.clusterName, {
  144. method: 'POST',
  145. data: Y.JSON.stringify(assignHostsRequestData),
  146. timeout : App.io.DEFAULT_AJAX_TIMEOUT_MS,
  147. on: {
  148. start: function(x, o) {
  149. App.ui.showLoadingOverlay();
  150. },
  151. complete: function(x, o) {
  152. e.target.set('disabled', false);
  153. App.ui.hideLoadingOverlay();
  154. },
  155. success: function (x,o) {
  156. var clusterConfigJson;
  157. e.target.set('disabled', false);
  158. Y.log("RAW JSON DATA: " + o.responseText);
  159. // Process the JSON data returned from the server
  160. try {
  161. clusterConfigJson = Y.JSON.parse(o.responseText);
  162. }
  163. catch (e) {
  164. alert("JSON Parse failed!");
  165. return;
  166. }
  167. //Y.log("PARSED DATA: " + Y.Lang.dump(clusterConfigJson));
  168. if (clusterConfigJson.result != 0) {
  169. // Error!
  170. alert("Got error!" + clusterConfigJson.error);
  171. return;
  172. }
  173. clusterConfigJson = clusterConfigJson.response;
  174. /* Done with this stage, transition to the next. */
  175. App.transition.transitionToNextStage( "#assignHostsCoreDivId", assignHostsRequestData,
  176. "#configureClusterCoreDivId", clusterConfigJson, renderConfigureCluster );
  177. },
  178. failure: function (x,o) {
  179. e.target.set('disabled', false);
  180. alert(App.io.DEFAULT_AJAX_ERROR_MESSAGE);
  181. }
  182. }
  183. });
  184. });
  185. // prevValue is used to undo user selection in case we prevent the user from assigning a service
  186. var prevValue = '';
  187. $('#masterServicesToHosts select').off('click');
  188. $('#masterServicesToHosts select').click(function() {
  189. prevValue = $(this).val();
  190. }).change(function(event) {
  191. var masterName = $(this).attr('name');
  192. // masterServices[masterName] = $(this).val();
  193. var prevChosenHost = $('#' + masterName + 'ChosenHost').val();
  194. var newChosenHost = $(this).val();
  195. if (addMasterServiceToHost(masterName, newChosenHost, hostsToMasterServices, masterServices)) {
  196. removeMasterServiceFromHost(masterName, prevChosenHost, hostsToMasterServices);
  197. renderHostsToMasterServices(hostsToMasterServices);
  198. $('#' + masterName + 'ChosenHost').val(newChosenHost);
  199. } else {
  200. $(this).val(prevValue);
  201. }
  202. });
  203. }
  204. this.render = function (clusterInfo) {
  205. App.ui.hideLoadingOverlay();
  206. Y.log("Render assign hosts data " + Y.Lang.dump(clusterInfo));
  207. Y.one('#assignHostsCoreDivId').setStyle("display", "block");
  208. App.props.clusterName = clusterInfo.clusterName;
  209. allHosts = clusterInfo.allHosts;
  210. managerHostName = clusterInfo.managerHostName;
  211. var servicesInfo = Y.Array( clusterInfo.services );
  212. masterServices = {};
  213. Y.Array.each(servicesInfo, function(serviceInfo) {
  214. if( serviceInfo.enabled == true ) {
  215. var zkIndex = 1;
  216. Y.Array.each(serviceInfo.masters, function(masterInfo) {
  217. for (var i in masterInfo.hostNames) {
  218. var masterHostInfo = {
  219. 'name' : masterInfo.name,
  220. 'displayName' : masterInfo.displayName,
  221. 'host' : masterInfo.hostNames[i]
  222. };
  223. // there could be multiple zookeepers
  224. if (masterInfo.name == 'ZOOKEEPER_SERVER') {
  225. masterHostInfo.name = 'ZOOKEEPER_SERVER_' + zkIndex;
  226. masterHostInfo.displayName = masterHostInfo.displayName + ' ' + zkIndex;
  227. zkIndex++;
  228. }
  229. masterServices[masterHostInfo.name] = masterHostInfo;
  230. }
  231. });
  232. }
  233. });
  234. hostsToMasterServices = {};
  235. var markup = '';
  236. for (var i in masterServices) {
  237. markup += '<div class="masterServiceSelect" id=' + masterServices[i].name + 'Id' + '><label><b>'
  238. + masterServices[i].displayName
  239. + '</b></label>' + getMasterHostSelect(masterServices[i].name, masterServices[i].host)
  240. + '</div>';
  241. if (hostsToMasterServices[masterServices[i].host] == null) {
  242. hostsToMasterServices[masterServices[i].host] = {};
  243. }
  244. hostsToMasterServices[masterServices[i].host][masterServices[i].name] = masterServices[i].displayName;
  245. }
  246. // add manager server
  247. if (hostsToMasterServices[managerHostName] == null) {
  248. hostsToMasterServices[managerHostName] = {};
  249. }
  250. hostsToMasterServices[managerHostName].MANAGER_SERVER = App.props.managerServiceName + ' Server';
  251. Y.one('#masterServicesToHosts').setContent(markup);
  252. // BEGIN KERBEROS HANDLING
  253. // At the time of load of the page if Kerberos selection div is already
  254. // present then remove it
  255. var kerbPresent = Y.one("#existingKerberosServerId");
  256. if (kerbPresent) {
  257. Y.one("#masterServicesToHostsContainer").removeChild(kerbPresent);
  258. }
  259. kerbPresent = Y.one("#KERBEROS_SERVERId");
  260. if (kerbPresent) {
  261. var markup = '<div name="existingKerberosServer" id="existingKerberosServerId" style="clear:both;float:none;margin-bottom:12px">'
  262. + '<label class="checkbox" for="useExistingKerberos" style="padding-left:70px; display:block;">'
  263. + '<em>'
  264. + 'Use self-configured Kerberos Server'
  265. + '</em>'
  266. + '<input type="checkbox" name="useExistingKerberos" id="useExistingKerberos" style="position:relative;">'
  267. + '</label>'
  268. + '</div>';
  269. Y.one("#masterServicesToHostsContainer").prepend(markup);
  270. markup = '<input class type="text" name="existingKerberosHostname" id="existingKerberosHostname" placeholder="Enter host name" value="" style="display:none;">';
  271. kerbPresent.one('label').insert(markup, 'after');
  272. Y.one('#useExistingKerberos').on('click', function(e) {
  273. var selectKerbNode = Y.one('#KERBEROS_SERVERId select');
  274. var existingKerberosHostname = Y.one('#existingKerberosHostname');
  275. if (this.get('checked')) {
  276. selectKerbNode.hide();
  277. existingKerberosHostname.show();
  278. } else {
  279. selectKerbNode.show();
  280. existingKerberosHostname.hide();
  281. }
  282. renderHostsToMasterServices(hostsToMasterServices);
  283. });
  284. }
  285. // END KERBEROS HANDLING
  286. renderHostsToMasterServices(hostsToMasterServices);
  287. attachEventHandlers();
  288. }; // end render
  289. };