You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by vi...@apache.org on 2012/06/06 00:35:51 UTC

svn commit: r1346636 - in /incubator/ambari/branches/ambari-186: CHANGES.txt hmc/css/common.css hmc/html/initializeCluster.php hmc/js/assignMasters.js hmc/php/db/HMCDBAccessor.php hmc/php/frontend/selectServices.php hmc/php/util/selectNodes.php

Author: vikram
Date: Tue Jun  5 22:35:51 2012
New Revision: 1346636

URL: http://svn.apache.org/viewvc?rev=1346636&view=rev
Log:
AMBARI-347. Redo master service assignment page  (Contributed by Yusaku)

Modified:
    incubator/ambari/branches/ambari-186/CHANGES.txt
    incubator/ambari/branches/ambari-186/hmc/css/common.css
    incubator/ambari/branches/ambari-186/hmc/html/initializeCluster.php
    incubator/ambari/branches/ambari-186/hmc/js/assignMasters.js
    incubator/ambari/branches/ambari-186/hmc/php/db/HMCDBAccessor.php
    incubator/ambari/branches/ambari-186/hmc/php/frontend/selectServices.php
    incubator/ambari/branches/ambari-186/hmc/php/util/selectNodes.php

Modified: incubator/ambari/branches/ambari-186/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/CHANGES.txt?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/CHANGES.txt (original)
+++ incubator/ambari/branches/ambari-186/CHANGES.txt Tue Jun  5 22:35:51 2012
@@ -6,6 +6,8 @@ characters wide.
 
 Release 0.1.x - unreleased
 
+  AMBARI-347. Redo master service assignment page (Yusaku via Vikram)
+
   AMBARI-339. Making transitionToNextStage more robust (Vikram)
 
   AMBARI-345. Make TxnProgressWidget More Robust In The Face Of Un-Ready Txn Stages (Varun via Vikram)

Modified: incubator/ambari/branches/ambari-186/hmc/css/common.css
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/css/common.css?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/css/common.css (original)
+++ incubator/ambari/branches/ambari-186/hmc/css/common.css Tue Jun  5 22:35:51 2012
@@ -416,6 +416,7 @@ div.separator {
 }
 #masterServices a {
 	margin-left:20px;
+	margin-top:20px;
 }
 #masterServicesToHosts {
 	margin-left:20px;
@@ -437,15 +438,36 @@ div.separator {
     border: 1px solid rgba(0, 0, 0, 0.05);
     border-radius: 4px 4px 4px 4px;
     box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
-    margin: 0 0 20px;
+    margin: 0 0 10px;
     min-height: 20px;
-    padding: 19px;
+    padding: 10px 20px;
     width:400px;
 }
-.hostToMasterServices h3 {
+.hostToMasterServices > h3 {
 	font-size:14px;
+	margin-bottom:4px!important;
+	line-height:14px;
+}
+.hostToMasterServices ul {
+	margin-left:0;
+	margin-bottom:0;
+	font-size:10px;
+	list-style:none;
+}
+.hostToMasterServices ul:after {
+	clear:both;
+}
+.hostToMasterServices li {
+	float:left;
+	background-color:#65B642;
+	padding:4px 6px;
+	color:#fff;
+	margin-right:10px;
+	margin-top:6px;
+	border-radius:4px;
+	-webkit-border-radius:4px;
+	-moz-border-radius:4px;
 }
-
 .navbar .brand {
     color: #666666;
     display: block;

Modified: incubator/ambari/branches/ambari-186/hmc/html/initializeCluster.php
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/html/initializeCluster.php?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/html/initializeCluster.php (original)
+++ incubator/ambari/branches/ambari-186/hmc/html/initializeCluster.php Tue Jun  5 22:35:51 2012
@@ -192,10 +192,11 @@
                 </div>
                 <div id="formStatusDivId" class="formStatusBar" style="display:none">					
                 </div>               
-                <div id="serviceMastersLinksDivId">
-                </div>
-                <div id="nodeGroupsCoreDivId">
+                <div id="masterServices">
+                  <div id="masterServicesToHosts"></div>
+                  <div id="hostsToMasterServices"></div>
                 </div>
+                <div style="clear:both"></div>
                 <a href="javascript:void 0" style="margin:20px" class="btn btn-large" id="selectServiceMastersSubmitButtonId"><?php echo $RES['initWizard.assignMasters.submit.label'] ?></a>
               </div>
 

Modified: incubator/ambari/branches/ambari-186/hmc/js/assignMasters.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/js/assignMasters.js?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/js/assignMasters.js (original)
+++ incubator/ambari/branches/ambari-186/hmc/js/assignMasters.js Tue Jun  5 22:35:51 2012
@@ -1,127 +1,13 @@
 var registeredAssignHostsEventHandlers = false;
 
-var nodeAssignments;
-// TODO: Limit the number of groups
-var staticNodeGroups;
-var nodeGroups;
-var possibleGroups;
-var numSlotsPerGroup;
-
-function getAssociativeArrayLength( associateArray ) {
-  var element_count = 0;
-  for(var e in associateArray) {
-    if(associateArray.hasOwnProperty(e)) {
-      element_count++; 
-    }
-  }
-  return element_count;
-}
-
-var changeNodeLocked = false; // only once change node at a time
-function changeNode(nodeGroupName, slotNumber) {
-  if (changeNodeLocked) {
-    setFormStatus("You are already in the process of changing node, let's finish that first!", true);
-    return;
-  }
-  changeNodeLocked = true;
-  var slotId = nodeGroupName + slotNumber;
-  var hostListMarkup = "";
-  var moreHostsLeft = false;
-  for (hostIndex in possibleGroups[nodeGroupName].hosts) {
-    var hostName = possibleGroups[nodeGroupName].hosts[hostIndex];
-    if (!isNodeAssigned(nodeGroupName, hostName)) { 
-      moreHostsLeft = true;
-      hostListMarkup += '<a href=\'javascript:setNodeAssignment("' + slotId + '", "'  + hostName + '")\'>' + hostName + '</a><br/>';
-    }
-  }
-  if (!moreHostsLeft) {
-   setFormStatus("All hosts are already assigned in Node-Group " + nodeGroupName, true);
-   changeNodeLocked = false;
-  } else {
-    hoverOnANode(slotId);
-    globalYui.Node.create('<div id="nodeListDynamicId"></div>').appendTo(globalYui.one("#assignHostsCoreDivId"));
-    globalYui.one("#nodeGroupsCoreDivId").setStyle("width", "80%");;
-    globalYui.one("#nodeListDynamicId").setContent(hostListMarkup);
-    var heightOfNodeTable = globalYui.one("#nodeGroupsCoreDivId").getComputedStyle("height");
-    globalYui.one("#nodeListDynamicId").setStyle("margin-top", "-" + heightOfNodeTable );
-    globalYui.one("#nodeListDynamicId").setStyle("height", heightOfNodeTable);
-  }
-}
-
-function hoverOnANode(slotId) {
-  globalYui.one("#nodeAssignmentWrapper" + slotId + "Id").replaceClass("nodeAssignmentWrapper", "nodeAssignmentWrapperHover");
-  globalYui.one("#slotForGroup" + slotId).replaceClass("slot", "slotHover");
-}
-
-function hoverSlotForGroup(slotId) {
-  globalYui.log("hovered on " + "#SlotForGroup" + slotId + "Id");
-  hoverOnANode(slotId);
-}
-
-function hoverNodeAssignment(slotId) {
-  globalYui.log("hovered on " + "#nodeAssignment" + slotId + "Id");
-  hoverOnANode(slotId);
-}
-
-function mouseOutNode(slotId) {
-  globalYui.one("#nodeAssignmentWrapper" + slotId + "Id").replaceClass("nodeAssignmentWrapperHover", "nodeAssignmentWrapper");
-  globalYui.one("#slotForGroup" + slotId).replaceClass("slotHover", "slot");
-}
-
-function mouseOutSlotForGroup(slotId) {
-  globalYui.log("mouseOut on " + "#slotForGroup" + slotId + "Id");
-  mouseOutNode(slotId);
-}
-
-function mouseOutNodeAssignment(slotId) {
-  globalYui.log("mouseOut on " + "#nodeAssignment" + slotId + "Id");
-  mouseOutNode(slotId);
-}
-
-function isNodeAssigned(nodeGroupName, hostName) {
-  for (slotId in nodeAssignments) {
-    if (nodeAssignments[slotId] == hostName) {
-      globalYui.log(hostName + " is already assigned");
-      return true;
-    }
-  }
-  globalYui.log(hostName + " is not assigned");
-  return false;
-}
-
-function setNodeAssignment(slotId, hostName) {
-  nodeAssignments[slotId] = hostName;
-  globalYui.one("#nodeAssignment" + slotId + 'Id').setContent(nodeAssignments[slotId]);
-  globalYui.one("#nodeListDynamicId").setContent("");
-  globalYui.one("#nodeListDynamicId").setStyle("display", "none");
-  globalYui.one("#nodeListDynamicId").remove();
-  setFormStatus("Changed Node # " + slotId + " to " + hostName, false);
-  globalYui.one("#nodeGroupsCoreDivId").setStyle("width", "100%");;
-  mouseOutNode(slotId);
-  // Release the lock
-  changeNodeLocked = false;
-}
-
-function renderNodeAssignments() {
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      var nodeAssignmentDivId = "#nodeAssignment" + nodeGroupName + i + 'Id';
-      var nodeAssignmentDiv = globalYui.one(nodeAssignmentDivId);
-      nodeAssignmentDiv.setContent(nodeAssignments[nodeGroupName + i]);
-    }
-  }
-}
-
 function getNodeInfo (allHosts, nodeName) {
-
-  globalYui.log("nodename: " + nodeName);
+  // globalYui.log("nodename: " + nodeName);
   if (nodeName == null) {
     return null;
   }
   for (host in allHosts) {
     if (allHosts[host].hostName == nodeName) {
-      globalYui.log("Get node info: " + allHosts[host].hostName);
+      // globalYui.log("Get node info: " + allHosts[host].hostName);
       return allHosts[host];
     }
   }
@@ -129,154 +15,72 @@ function getNodeInfo (allHosts, nodeName
   return null;
 }
 
-function findNodeGroup (nodeName, nodeGroups, possibleGroups) {
-  var position = 0;
-  var retval = {};
-
-  for (nodeGroup in nodeGroups) {
-    globalYui.log("Node group: " + globalYui.Lang.dump(nodeGroups));
-    nodeGroupId = nodeGroups[nodeGroup];
-    
-    globalYui.log("Hosts for group: " + globalYui.Lang.dump(possibleGroups[nodeGroupId].hosts));
-    for (host in possibleGroups[nodeGroupId].hosts) {
-      globalYui.log("Node: " + possibleGroups[nodeGroupId].hosts[host]);
-      if (possibleGroups[nodeGroupId].hosts[host] == nodeName) {
-        retval = {
-          'nodeGroupId'   : nodeGroupId,
-          'nodePosition'  : position
-        };
-        return retval;
-      } else {
-        position++;
-      }
-    }
-  }
+function addCommasToInt(num) {
+	return num.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
 }
 
-function getNodeGroupId (nodeName, nodeGroups, possibleGroups) {
-
-  var nodeGroupIndex;
-  var nodeId = 0;
-  if (nodeName == null) {
-    nodeGroupIndex = nodeGroups[0];
-    globalYui.log("Default group index: " + nodeGroupIndex);
-  } else {
-    globalYui.log("Node name: " + globalYui.Lang.dump(nodeName));
-    globalYui.log("node grps: " + globalYui.Lang.dump(nodeGroups));
-    globalYui.log("possible grps: " + globalYui.Lang.dump(possibleGroups));
-    nodeGroupInfo = findNodeGroup(nodeName, nodeGroups, possibleGroups);
-    nodeGroupIndex = nodeGroupInfo.nodeGroupId;
-    nodeId = nodeGroupInfo.nodePosition;
-  }
-  var id = 'slotForGroup' + nodeGroupIndex + nodeId;
-
-  globalYui.log("Node group index: " + nodeGroupIndex);
-
-  return id;
+function renderHostsToMasterServices(allHosts, hostsToMasterServices) {
+	var markup = '';
+	for (var host in hostsToMasterServices) {
+		  var hostInfo = getNodeInfo(allHosts, host);
+		  markup += '<div class="hostToMasterServices"><h3>' + host + '<span class="hostInfo">' + addCommasToInt(hostInfo.totalMem) + 'MB RAM, ' + hostInfo.cpuCount + ' cores</span></h3><ul>';
+		  for (var j in hostsToMasterServices[host]) {
+			  markup += '<li>' + hostsToMasterServices[host][j] + '</li>';
+		  }
+		  markup += '</ul><div style="clear:both"></div></div>';
+	}
+	$('#hostsToMasterServices').html(markup);
+}
+
+function addMasterServiceToHost(masterName, hostName, hostsToMasterServices, masterServices) {
+	if (hostsToMasterServices[hostName] == null) {
+		hostsToMasterServices[hostName] = {};
+	}
+	hostsToMasterServices[hostName][masterName] = masterServices[masterName].displayName;
+}
+
+function removeMasterServiceFromHost(masterName, hostName, hostsToMasterServices) {
+	for (var i in hostsToMasterServices[hostName]) {
+		if (i == masterName) {
+			delete hostsToMasterServices[hostName][i];
+			//alert(Object.keys(hostsToMasterServices[hostName]).length);
+			if (Object.keys(hostsToMasterServices[hostName]).length == 0) {
+				//alert('remove');
+				delete hostsToMasterServices[hostName];
+			}
+			return;
+		}
+	}
+}
+
+function getMasterHostSelect(masterName, allHosts, chosenHostName) {
+	var chosenHost = getNodeInfo(allHosts, chosenHostName);
+	var markup = '<select name="' + masterName + '">'; 
+	markup += '<option selected="selected" value="' + chosenHost.hostName + '">' + chosenHost.hostName + ' - ' + addCommasToInt(chosenHost.totalMem) + 'MB RAM, ' + chosenHost.cpuCount + ' cores</option>';
+	for (var i in allHosts) {
+      var host = allHosts[i];
+	  if (host.hostName != chosenHost.hostName) {
+	    markup += '<option value="' + host.hostName + '">' + host.hostName + ' - ' + addCommasToInt(host.totalMem) + 'MB RAM, ' + host.cpuCount + ' cores</option>';
+	  }
+	}
+	markup += '</select><input type="hidden" style="display:none" id="' + masterName + 'ChosenHost" value="' + chosenHost.hostName + '">';
+	return markup;
 }
 
-function hasHost (list, hostName) {
-  var host
-  for (host in list) {
-    if (list[host].hostName == hostName) {
-      globalYui.log("Host name found: " + hostName);
-      return true;
-    }
-  }
-
-  globalYui.log("Host name not found: " + hostName);
-  return false;
-}
-
-// excludes the elements of the prunelist from allHosts
-function pruneHostList (allHosts, pruneList) {
-  var retval = {};
-
-  var node;
-  for (node in allHosts) {
-    if (hasHost(pruneList, allHosts[node].hostName) == false) {
-      retval[allHosts[node].hostName] = allHosts[node];
-    }
-  }
-
-  return retval;
-}
-
-// returns a tuple of possible groups and node groups
-function constructNodeGroups (hostList, currPossibleGroups, currNodeGroups) {
-  globalYui.log("current possible: " + globalYui.Lang.dump(currPossibleGroups));
-  globalYui.log("current nodes: " + globalYui.Lang.dump(currNodeGroups));
-  globalYui.log("hostlist: " + globalYui.Lang.dump(hostList));
-  possibleGroups = currPossibleGroups;
-  nodeGroups = currNodeGroups;
-  // Construct node-groups now
-  for (hostInfo in hostList) {
-    host = hostList[hostInfo];
-//  globalYui.Array.each( hostList, function(host) {
-    var totalMem = host.totalMem;
-    var numCpus = host.cpuCount;
-    var found = false;
-    globalYui.log("Looking at host " + host.hostName);
-    for (groupIndex in possibleGroups) {
-      var thisGroup = possibleGroups[groupIndex];
-      if (thisGroup.totalMem == totalMem && thisGroup.numCpus == numCpus) {
-        found = true;
-        globalYui.log("Using an existing nodeGroup " + groupIndex );
-        thisGroup.hosts.push(host.hostName);
-        break;
-      }
-    }
-
-    if (!found) {
-      // Not found create a new group
-      var newGroup = { "totalMem": totalMem, "numCpus": numCpus, "hosts" : [ host.hostName ] };
-      var newGroupName = staticNodeGroups[getAssociativeArrayLength(possibleGroups)];
-      possibleGroups[newGroupName] = newGroup;
-      nodeGroups.push(newGroupName);
-      globalYui.log("Added a new group " + newGroupName);
-    }
-  }
-//  });
-
-  retval = {
-    'possibleGroups' : possibleGroups,
-    'nodeGroups' : nodeGroups
-  };
-
-  return retval;
-}
-
-function renderAssignHosts (clusterInfo) {
+function renderAssignHosts(clusterInfo) {
 
   hideLoadingImg();
   globalYui.one('#assignHostsCoreDivId').setStyle("display", "block");
 
-  // Mapping from slotIDs to hostNames
-  nodeAssignments = {};
-  // TODO: Limit the number of groups
-  staticNodeGroups = [ "A", "B", "C", "D"];
-  // Array of names of groups
-  nodeGroups = [];
-  // Mapping of group-name to hosts
-  possibleGroups = { };
-  // Mapping of group-name to number of slots in that group
-  numSlotsPerGroup = {};
-  // Mapping of slot-id to Array of masters
-  var slotContents = {};
-  // Mapping of master-Name to slotId
-  var serviceLocations = {};
-
   if( !registeredAssignHostsEventHandlers ) {
 
     globalYui.one('#selectServiceMastersSubmitButtonId').on('click', function (e) {
       e.target.set('disabled', true);
 
       var assignHostsRequestData = {};
-      for (masterName in serviceLocations) {
-        var pollutedSlotId = serviceLocations[masterName];
-        var slotId = pollutedSlotId.replace(/slotForGroup/, "");
-        assignHostsRequestData[ masterName ] = nodeAssignments[slotId];
-        globalYui.log("Assignment for " + masterName + " is " + nodeAssignments[slotId]);
+      for (var masterName in masterServices) {
+        assignHostsRequestData[masterName] = $('select[name=' + masterName + ']').val();
+        // globalYui.log("Assignment for " + masterName + " is " + assignHostsRequestData[masterName]);
       };
 
       globalYui.io("../php/frontend/assignMasters.php?clusterName="+clusterInfo.clusterName, {
@@ -333,185 +137,49 @@ function renderAssignHosts (clusterInfo)
 
   var allHosts = clusterInfo.allHosts;
   var servicesInfo = globalYui.Array( clusterInfo.services );
-  var serviceMasters = [ ];
-  var serviceMastersDisplayNames = {};
-  var suggestNodes = {};
+  var masterServices = {};
+
   globalYui.Array.each(servicesInfo, function(serviceInfo) {
     if( serviceInfo.enabled == true ) {
       globalYui.Array.each(serviceInfo.masters, function(masterInfo) {
         var masterHostInfo = {
           'name' : masterInfo.name,
+          'displayName' : masterInfo.displayName,
           'host' : masterInfo.hostName
         };
 
-        serviceMasters.push(masterHostInfo);
-        serviceMastersDisplayNames[masterInfo.name] = masterInfo.displayName;
+        masterServices[masterInfo.name] = masterHostInfo;
 
-        if ((retval = getNodeInfo(allHosts, masterInfo.hostName)) != null) {
-          suggestNodes[masterInfo.hostName] = retval;
-        }
       });
     }
   });
-
-  // construct possible and node groups with the suggested nodes first
-  // before calling the same with allHosts (pruned) 
-  globalYui.log("Suggest nodes: " + globalYui.Lang.dump(suggestNodes));
-  retval = constructNodeGroups(suggestNodes, possibleGroups, nodeGroups);
-
-  possibleGroups = retval.possibleGroups;
-  nodeGroups = retval.nodeGroups;
-
-  retval = pruneHostList(allHosts, suggestNodes);
-
-  globalYui.log("Pruned list: " + globalYui.Lang.dump(retval));
-  retval = constructNodeGroups(retval, possibleGroups, nodeGroups);
-  possibleGroups = retval.possibleGroups;
-  nodeGroups = retval.nodeGroups;
-
-  globalYui.log("Possible groups: " + globalYui.Lang.dump(possibleGroups));
-  globalYui.log("Groups: " + globalYui.Lang.dump(nodeGroups));
-
-  /*
-  // For testing
-  possibleGroups["C"] = {"totalMem": 1234, "numCpus":5, "hosts" : [ "dummy1.hortonworks.com", "dummy2.hortonworks.com", "dummy3.hortonworks.com", "dummy4.hortonworks.com", "dummy5.hortonworks.com", "dummy6.hortonworks.com", "dummy7.hortonworks.com", "dummy8.hortonworks.com" ] };
-  nodeGroups.push("C");
-
-  possibleGroups["D"] = {"totalMem": 12345, "numCpus":6, "hosts" : [ "dumm101.hortonworks.com", "dummy102.hortonworks.com", "dummy103.hortonworks.com", "dummy104.hortonworks.com" ] };
-  nodeGroups.push("D");
-  */
-
-  /////////// Figure out the numSlots per group
-  var numServices = serviceMasters.length;
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    var numNodes = possibleGroups[nodeGroupName].hosts.length;
-    numSlotsPerGroup[nodeGroupName] = numServices < numNodes ? numServices : numNodes ;
-  }
-
-  ////////////////// Render node groups ////////
-  var nodeGroupsMarkup = "";
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    nodeGroupsMarkup += '<div id="nodeGroupsTable">';
-    globalYui.log("Rendering nodeGroup for " + nodeGroupName);
-    var nodeGroupConfig = possibleGroups[nodeGroupName];
-    nodeGroupsMarkup += '<div class="nodeGroupTitle">Node group ' + nodeGroupName + ' has ' + nodeGroupConfig.hosts.length + ' nodes each with ' + nodeGroupConfig.totalMem + 'MB memory and ' + nodeGroupConfig.numCpus + ' cores.</div>';
-    nodeGroupsMarkup += '<div id="' + nodeGroupName + '" class="aNodeGroup">';
-
-    // Number of boxes equal to number of service-masters
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      nodeGroupsMarkup +=       '<div class="slotBucket">' + 
-        '<div class="slotTitle"> Node # ' + ( i + 1) + '</div>' +
-        '<div id="slotForGroup' + nodeGroupName + i + '" class="slot" onmouseover=\'javascript:hoverSlotForGroup("' + nodeGroupName + i + '");\' onmouseout=\'javascript:mouseOutSlotForGroup("' + nodeGroupName + i + '");\'></div>' +
-        '</div>';
-  } 
-  nodeGroupsMarkup +=     '</div>'; 
-
-  ////////////////// Create node list per group ////////////////
-  //var nodeListContent = '<div class="nodeList">Nodes assignment for group ' + nodeGroupName + ':<br/>';
-  var nodeListContent = '<div class="nodeList">';
-  //var nodeListContent = '';
-  for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-    var slotId = nodeGroupName + i;
-    nodeListContent += '<div class="nodeAssignmentWrapper" id="nodeAssignmentWrapper' + slotId + 'Id">Node # ' + ( i + 1) + ': ' +
-                         '<div class="nodeAssignment" id="nodeAssignment' + slotId + 'Id" onmouseover=\'javascript:hoverNodeAssignment("' + slotId + '");\' onmouseout=\'javascript:mouseOutNodeAssignment("' + slotId + '");\'></div>' +
-                         '&nbsp;' +
-                         '<a href=\'javascript:changeNode("' + nodeGroupName + '", "' + i + '");\' id="changeLink' + slotId + '">change</a>' +
-                         '<br/>' +
-                       '</div>';
-  }
-  nodeListContent += "</div>";
-  nodeGroupsMarkup += nodeListContent;
-  ////////////////// End of creating node list per group //////
-
-  nodeGroupsMarkup += '</div>';
-  }
-
-  globalYui.one("#nodeGroupsCoreDivId").setContent(nodeGroupsMarkup);
-  ////////////////// End of rendering node groups ////////
-
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      var thisId = 'slotForGroup' + nodeGroupName + i;
-      if (slotContents[thisId] === undefined) {
-        slotContents[thisId] = {};
-      }
-    }
-  }
-
-  ////////////////// Initialize all masters in some group for now ///////////////////
-  var todoId = 'slotForGroup' + nodeGroups[0] + 0;
-  for (serviceMasterIndex in serviceMasters) {
-    var todoId = getNodeGroupId(serviceMasters[serviceMasterIndex].host, 
-                                nodeGroups, possibleGroups);
-    var masterName = serviceMasters[serviceMasterIndex].name;
-    slotContents[todoId][masterName] = masterName;
-    serviceLocations[masterName] = todoId;
-  }
-
-  // Now render
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      var thisId = 'slotForGroup' + nodeGroupName + i;
-      var content= "";
-      for (master in slotContents[thisId]) {
-        content += '<div id="' + master + '" class="masterDiv">' + serviceMastersDisplayNames[master] + "</div>";
-      }
-      globalYui.one('#' + thisId).setContent(content);
-    }
-  }
-  ////////////////// End of initializing all slots ///////////////////
-
-  ///////////////// Initialize node assignments //////////////////////
-  // Start with first set of hosts in all groups
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      globalYui.log("setting nodeAssignments for " + nodeGroupName + i + " to " + possibleGroups[nodeGroupName].hosts[i]);
-      nodeAssignments[nodeGroupName + i] = possibleGroups[nodeGroupName].hosts[i];
-    }
-  }
-  // Now render
-  renderNodeAssignments();
-  ///////////////// End of initing node assignments //////////////////////
-
-  for (serviceMasterIndex in serviceMasters) {
-    var dd = new globalYui.DD.Drag({
-      node: globalYui.one('#' + serviceMasters[serviceMasterIndex].name)
-  }).plug(globalYui.Plugin.DDProxy, {
-    //We don't want the node to move on end drag
-    moveOnEnd: false
-  }).plug(globalYui.Plugin.DDConstrained, {
-    //Keep it inside the work area
-    constrain2node: '#nodeGroupsCoreDivId'
+  
+  var hostsToMasterServices = {};
+  var markup = '';
+  for (var i in masterServices) {
+	  markup += '<div class="masterServiceSelect"><label><b>'
+	  	+ masterServices[i].displayName
+	    + '</b> assigned to</label>' + getMasterHostSelect(masterServices[i].name, allHosts, masterServices[i].host)
+		+ '</div>';
+	  if (hostsToMasterServices[masterServices[i].host] == null) {
+		  hostsToMasterServices[masterServices[i].host] = {};
+	  } 
+	  hostsToMasterServices[masterServices[i].host][masterServices[i].name] = masterServices[i].displayName;
+  }
+  
+  $('#masterServicesToHosts').html(markup);
+  
+  renderHostsToMasterServices(allHosts, hostsToMasterServices);
+  
+  $('select').change(function() {
+	  var masterName = $(this).attr('name');
+	  // masterServices[masterName] = $(this).val();
+	  var prevChosenHost = $('#' + masterName + 'ChosenHost').val();
+	  var newChosenHost = $(this).val();
+	  removeMasterServiceFromHost(masterName, prevChosenHost, hostsToMasterServices);
+	  addMasterServiceToHost(masterName, newChosenHost, hostsToMasterServices, masterServices);
+	  renderHostsToMasterServices(allHosts, hostsToMasterServices);
+	  $('#' + masterName + 'ChosenHost').val(newChosenHost);
   });
-  //Prevent the default end event (this moves the node back to its start position)
-  dd.on('drag:end', function(e) {
-    e.preventDefault();
-  });
-  }
-
-  for (nodeGroupIndex in nodeGroups) {
-    var nodeGroupName = nodeGroups[nodeGroupIndex];
-    for (var i=0;i<numSlotsPerGroup[nodeGroupName];i++) {
-      var thisId = '#slotForGroup' + nodeGroupName + i;
-      var drop = new globalYui.DD.Drop({
-        node: thisId
-    });
-    //Listen for a drop:hit on this target
-    drop.on('drop:hit', function(e) {
-      //Now we get the drag instance that triggered the drop hit
-      var draggedItem = e.drag.get('node');
-      var dropPlace = this.get('node');
-      dropPlace.appendChild(draggedItem);
-      serviceLocations[draggedItem.get('id')] = dropPlace.get('id');
-      var msg = "Moved " + draggedItem.get('id') + " to " + dropPlace.get('id');
-      setFormStatus(msg, false);
-      globalYui.log(msg);
-    });
-    }
-  }
+  
 }

Modified: incubator/ambari/branches/ambari-186/hmc/php/db/HMCDBAccessor.php
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/php/db/HMCDBAccessor.php?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/php/db/HMCDBAccessor.php (original)
+++ incubator/ambari/branches/ambari-186/hmc/php/db/HMCDBAccessor.php Tue Jun  5 22:35:51 2012
@@ -971,6 +971,9 @@ class HMCDBAccessor {
    *      "sortColumn" => "totalMem",
    *      "sortOrder" => "ASC/DESC"
    *      )
+   *   - optionally, an array of [ "sortColumn" => $sortColumn, "sortOrder" => $sortOrder]
+   *     can be used
+   *      
    * @return mixed
    *   array (
    *       "result" => 0,
@@ -1017,30 +1020,46 @@ class HMCDBAccessor {
       }
     }
     $using_sort = FALSE;
-    if (isset($order) && is_array($order)
-        && isset($order["sortColumn"])) {
-      $using_sort = TRUE;
-      $query .= " ORDER BY ";
-      if ($order["sortColumn"] == "hostName") {
-        $query .= "host_name";
-      }
-      else if ($order["sortColumn"] == "ip") {
-        $query .= "ip";
-      }
-      else if ($order["sortColumn"] == "totalMem") {
-        $query .= "total_mem";
-      }
-      else if ($order["sortColumn"] == "cpuCount") {
-        $query .= "cpu_count";
-      }
-      else if ($order["sortColumn"] == "osArch") {
-        $query .= "os_arch";
-      }
-      else if ($order["sortColumn"] == "osType") {
-        $query .= "os_type";
-      }
-      if (isset($order["sortOrder"])) {
-        $query .= " ".$order["sortOrder"];
+    if (isset($order) && is_array($order)) {
+      if (sizeof($order) > 0) {
+        $query .= " ORDER BY ";
+        $using_sort = TRUE;
+      }
+      while (sizeof($order) > 0) {
+        // is it an array of arrays, for an array of sortColumn and sortOrder?        
+        if (is_array($order[0])) {
+          $this->logger->log_debug('yo');
+          $orderItem = array_shift($order);
+        } else {
+          $orderItem["sortColumn"] = array_shift($order);
+          $orderItem["sortOrder"] = array_shift($order);
+        }
+        if (isset($orderItem["sortColumn"])) {
+          if ($orderItem["sortColumn"] == "hostName") {
+            $query .= "host_name";
+          }
+          else if ($orderItem["sortColumn"] == "ip") {
+            $query .= "ip";
+          }
+          else if ($orderItem["sortColumn"] == "totalMem") {
+            $query .= "total_mem";
+          }
+          else if ($orderItem["sortColumn"] == "cpuCount") {
+            $query .= "cpu_count";
+          }
+          else if ($orderItem["sortColumn"] == "osArch") {
+            $query .= "os_arch";
+          }
+          else if ($orderItem["sortColumn"] == "osType") {
+            $query .= "os_type";
+          }
+          if (isset($orderItem["sortOrder"])) {
+            $query .= " ".$orderItem["sortOrder"];
+            if (sizeof($order) > 0) { 
+              $query .= ',';
+            }
+          }
+        }
       }
     }
 

Modified: incubator/ambari/branches/ambari-186/hmc/php/frontend/selectServices.php
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/php/frontend/selectServices.php?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/php/frontend/selectServices.php (original)
+++ incubator/ambari/branches/ambari-186/hmc/php/frontend/selectServices.php Tue Jun  5 22:35:51 2012
@@ -89,7 +89,13 @@ $jsonOutput["allHosts"] = array();
  * FIXME need to get all hosts from select Nodes script
  */
 $allHostsInfo = $dbAccessor->getAllHostsInfo($clusterName,
-    array("=" => array ( "discoveryStatus" => "SUCCESS")), array());
+  array("=" => array ( "discoveryStatus" => "SUCCESS")),
+  array(
+    array("sortColumn" => "totalMem", "sortOrder" => "DESC"),
+    array("sortColumn" => "cpuCount", "sortOrder" => "DESC"),
+    array("sortColumn" => "hostName", "sortOrder" => "ASC")
+  )
+);
 if ($allHostsInfo["result"] != 0 ) {
   $logger->log_error("Got error while getting hostsInfo ".$allHostsInfo["error"]);
   print json_encode($allHostsInfo);

Modified: incubator/ambari/branches/ambari-186/hmc/php/util/selectNodes.php
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/php/util/selectNodes.php?rev=1346636&r1=1346635&r2=1346636&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/php/util/selectNodes.php (original)
+++ incubator/ambari/branches/ambari-186/hmc/php/util/selectNodes.php Tue Jun  5 22:35:51 2012
@@ -118,6 +118,30 @@ class SelectNodes {
     return $result;
   }
 
+  /**
+   * Helper function to add ZooKeeper master server.
+   */
+  function addZooKeeperServer($serviceInfo, $result, $hostInfo) {
+    $result["mastersToHosts"]["ZOOKEEPER_SERVER"] = $this->createHostMap($hostInfo);
+    return $result;
+  }
+  
+  /**
+   * Helper function to add Ganglia master server.
+   */
+  function addGangliaServer($result, $hostInfo) {
+    $result["mastersToHosts"]["GANGLIA_MONITOR_SERVER"] = $this->createHostMap($hostInfo);
+    return $result;
+  }
+  
+  /**
+   * Helper function to add Nagios server.
+   */
+  function addNagiosServer($result, $hostInfo) {
+    $result["mastersToHosts"]["NAGIOS_SERVER"] = $this->createHostMap($hostInfo);
+    return $result;
+  }
+  
   /**
    * Adds all the slaves to the hostlist given whats enabled
    */
@@ -306,8 +330,11 @@ class SelectNodes {
 
   public function selectNodes($clustername, $db) {
     $return = array();
-    $order = array("sortColumn" => "totalMem",
-        "sortOrder" => "DESC");
+    $order = array(
+        array("sortColumn" => "totalMem", "sortOrder" => "DESC"),
+        array("sortColumn" => "cpuCount", "sortOrder" => "DESC"),
+        array("sortColumn" => "hostName", "sortOrder" => "ASC"),
+    );
     $allHostsDBInfo = $db->getAllHostsInfo($clustername,
         array("=" => array ( "discoveryStatus" => "SUCCESS")) , $order);
     if ($allHostsDBInfo["result"] != 0) {
@@ -332,7 +359,13 @@ class SelectNodes {
     $result["result"] = 0;
     $this->logger->log_debug(print_r($allHostsDBInfo, true));
     $this->logger->log_debug(print_r($services,true));
-    if ($numNodes == 1) {
+    // logic to avoid installing Nagios/Ganglia Master on the HMC node...
+    // commented out for now
+    //$thisHostName = trim(strtolower(exec('hostname -f')));
+    //$monitorIndex = ($thisHostName != $allHostsInfo[0]['hostName']) ? 0 : 1;
+    $monitorIndex = 0;
+    $this->logger->log_debug('num nodes='.$numNodes);  
+    if ( $numNodes == 1 ) {
       $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
       $result = $this->addSNameNode($services, $result, $allHostsInfo[0]);
       $result = $this->addJobTracker($services, $result, $allHostsInfo[0]);
@@ -340,6 +373,9 @@ class SelectNodes {
       $result = $this->addOozieServer($services, $result, $allHostsInfo[0]);
       $result = $this->addHiveServer($services, $result, $allHostsInfo[0]);
       $result = $this->addTempletonServer($services, $result, $allHostsInfo[0]);
+      $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
+      $result = $this->addGangliaServer($result, $allHostsInfo[0]);
+      $result = $this->addNagiosServer($result, $allHostsInfo[0]);
       return $result;
     }
     if ( $numNodes <= 5) {
@@ -350,6 +386,9 @@ class SelectNodes {
       $result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
       $result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
       $result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
+      $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
+      $result = $this->addGangliaServer($result, $allHostsInfo[$monitorIndex]);
+      $result = $this->addNagiosServer($result, $allHostsInfo[$monitorIndex]); 
       return $result;
     }
     if ( $numNodes <= 30) {
@@ -360,6 +399,9 @@ class SelectNodes {
       $result = $this->addOozieServer($services, $result, $allHostsInfo[2]);
       $result = $this->addHiveServer($services, $result, $allHostsInfo[2]);
       $result = $this->addTempletonServer($services, $result, $allHostsInfo[2]);
+      $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
+      $result = $this->addGangliaServer($result, $allHostsInfo[$monitorIndex]);
+      $result = $this->addNagiosServer($result, $allHostsInfo[$monitorIndex]);
       return $result;
     }
     if ( $numNodes > 30) {
@@ -370,6 +412,9 @@ class SelectNodes {
       $result = $this->addOozieServer($services, $result, $allHostsInfo[3]);
       $result = $this->addHiveServer($services, $result, $allHostsInfo[4]);
       $result = $this->addTempletonServer($services, $result, $allHostsInfo[4]);
+      $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
+      $result = $this->addGangliaServer($result, $allHostsInfo[$monitorIndex]);
+      $result = $this->addNagiosServer($result, $allHostsInfo[$monitorIndex]);
       return $result;
     }
   }