vcl-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jftho...@apache.org
Subject svn commit: r752583 - in /incubator/vcl/trunk/web/.ht-inc: utils.php xmlrpcWrappers.php
Date Wed, 11 Mar 2009 19:09:12 GMT
Author: jfthomps
Date: Wed Mar 11 19:09:12 2009
New Revision: 752583

URL: http://svn.apache.org/viewvc?rev=752583&view=rev
Log:
VCL-78

xmlrpcWrappers.php:
-added XMLRPCblockAllocation
-added XMLRPCprocessBlockTime

utils.php:
-added dbLastInsertID as an easier way to get the last insert id for inserts into tables with
auto incremented ids
-modified isAvailable: added $ignoreprivileges as an optional argument which allows for user
access privileges to be ignored when allocating computers
-modified getAvailableBlockComputerids: added $allocatedcompids as an argument which is an
array of computers that should not be included in the returned list
-modified xmlrpccall: added XMLRPCblockAllocation and XMLRPCprocessBlockTime as registered
functions

Modified:
    incubator/vcl/trunk/web/.ht-inc/utils.php
    incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php

Modified: incubator/vcl/trunk/web/.ht-inc/utils.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=752583&r1=752582&r2=752583&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/utils.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/utils.php Wed Mar 11 19:09:12 2009
@@ -1279,6 +1279,20 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn dbLastInsertID()
+///
+/// \return last insert id for $mysql_link_vcl
+///
+/// \brief calls mysql_insert_id for $mysql_link_vcl
+///
+////////////////////////////////////////////////////////////////////////////////
+function dbLastInsertID() {
+	global $mysql_link_vcl;
+	return mysql_insert_id($mysql_link_vcl);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn getOSList()
 ///
 /// \return $oslist - array of OSs
@@ -1317,7 +1331,7 @@
 /// \b minprocspeed - minimum speed of processor(s) needed for image\n
 /// \b minnetwork - minimum speed of network needed for image\n
 /// \b maxconcurrent - maximum concurrent usage of this iamge\n
-/// \b reloadtime - time in minutes for image to loaded\n
+/// \b reloadtime - time in minutes for image to be loaded\n
 /// \b deleted - 'yes' or 'no'; whether or not this image has been deleted\n
 /// \b test - 0 or 1; whether or not there is a test version of this image\n
 /// \b resourceid - image's resource id from the resource table\n
@@ -3359,7 +3373,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn isAvailable($images, $imageid, $start, $end, $os, $requestid,
-///                          $userid)
+///                          $userid, $ignoreprivileges)
 ///
 /// \param $images - array as returned from getImages
 /// \param $imageid - imageid from the image table
@@ -3370,6 +3384,10 @@
 /// timeslot to update a request, pass the request id that will be updated;
 /// otherwise, don't pass this argument
 /// \param $userid - (optional) id from user table
+/// \param $ignoreprivileges (optional, default=0) - 0 (false) or 1 (true) - set
+/// to 1 to look for computers from any that are mapped to be able to run the
+/// image; set to 0 to only look for computers from ones that are both mapped
+/// and that $userid has been granted access to through the privilege tree
 ///
 /// \return -1 if $imageid is limited in the number of concurrent reservations
 ///         available, and the limit has been reached
@@ -3380,7 +3398,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function isAvailable($images, $imageid, $start, $end, $os, $requestid=0,
-                     $userid=0) {
+                     $userid=0, $ignoreprivileges=0) {
 	global $requestInfo;
 	$requestInfo["start"] = $start;
 	$requestInfo["end"] = $end;
@@ -3525,10 +3543,12 @@
 		// otherwise, build a list of computers
 		else {
 			# get list of available computers
-			$resources = getUserResources(array("imageAdmin", "imageCheckOut"),
-			                              array("available"), 0, 0, $userid);
-			$computers = implode("','", array_keys($resources["computer"]));
-			$computers = "'$computers'";
+			if(! $ignoreprivileges) {
+				$resources = getUserResources(array("imageAdmin", "imageCheckOut"),
+				                              array("available"), 0, 0, $userid);
+				$usercomputers = implode("','", array_keys($resources["computer"]));
+				$usercomputers = "'$usercomputers'";
+			}
 			$alloccompids = implode(",", $allocatedcompids);
 
 			$schedules = implode(',', $scheduleids);
@@ -3554,9 +3574,10 @@
 			       .       "c.RAM >= i.minram AND "
 			       .       "c.procnumber >= i.minprocnumber AND "
 			       .       "c.procspeed >= i.minprocspeed AND "
-			       .       "c.network >= i.minnetwork AND "
-			       .       "c.id IN ($computers) AND "
-			       .       "c.id IN ($mappedcomputers) AND "
+			       .       "c.network >= i.minnetwork AND ";
+			if(! $ignoreprivileges)
+				$query .=   "c.id IN ($usercomputers) AND ";
+			$query .=      "c.id IN ($mappedcomputers) AND "
 			       .       "c.id NOT IN ($alloccompids) "
 			       . "ORDER BY (c.procspeed * c.procnumber) DESC, "
 			       .          "RAM DESC, "
@@ -3569,7 +3590,8 @@
 				}
 			}
 			# get computer ids available from block reservations
-			$blockids = getAvailableBlockComputerids($imageid, $start, $end);
+			$blockids = getAvailableBlockComputerids($imageid, $start, $end,
+			                                         $allocatedcompids);
 		}
 
 		#remove computers from list that are already scheduled
@@ -3791,7 +3813,8 @@
 			}
 		}
 		# get computer ids available from block reservations
-		$blockids = getAvailableBlockComputerids($imageid, $start, $end);
+		$blockids = getAvailableBlockComputerids($imageid, $start, $end,
+		                                         $allocatedcompids);
 
 		# remove computers from list that are already scheduled
 		$usedComputerids = array();
@@ -6360,11 +6383,13 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getAvailableBlockComputerids($imageid, $start, $end)
+/// \fn getAvailableBlockComputerids($imageid, $start, $end, $allocatedcompids)
 ///
 /// \param $imageid - id of an image
 /// \param $start - starting time in unix timestamp form
 /// \param $end - ending time in unix timestamp form
+/// \param $allocatedcompids - array of computer ids that have already been
+/// allocated while processing this request
 ///
 /// \return an array of computer ids
 ///
@@ -6372,7 +6397,7 @@
 /// in user is a part of that are available between $start and $end
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function getAvailableBlockComputerids($imageid, $start, $end) {
+function getAvailableBlockComputerids($imageid, $start, $end, $allocatedcompids) {
 	global $user;
 	$compids = array();
 	$groupids = implode(',', array_keys($user['groups']));
@@ -6380,6 +6405,7 @@
 		$groupids = "''";
 	$startdt = unixToDatetime($start);
 	$enddt = unixToDatetime($end);
+	$alloccompids = implode(",", $allocatedcompids);
 	$query = "SELECT c.computerid "
 	       . "FROM blockComputers c, "
 	       .      "blockRequest r, "
@@ -6387,15 +6413,16 @@
 	       .      "state s, "
 	       .      "computer c2 "
 	       . "WHERE r.groupid IN ($groupids) AND "
-	       .       "r.imageid = $imageid AND "
+	       .       "c.computerid = c2.id AND "
+	       .       "c2.currentimageid = $imageid AND "
 	       .       "r.expireTime > NOW() AND "
 	       .       "t.blockRequestid = r.id AND "
 	       .       "c.blockTimeid = t.id AND "
 	       .       "t.start < '$enddt' AND "
 	       .       "t.end > '$startdt' AND "
-	       .       "c.computerid = c2.id AND "
 	       .       "c2.stateid = s.id AND "
-	       .       "s.name != 'failed' "
+	       .       "s.name != 'failed' AND "
+	       .       "c2.id NOT IN ($alloccompids) "
 	       . "ORDER BY s.name";
 	$qh = doQuery($query, 101);
 	while($row = mysql_fetch_assoc($qh)) {
@@ -8069,6 +8096,8 @@
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetRequestConnectData", "xmlRPChandler");
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCendRequest", "xmlRPChandler");
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetRequestIds", "xmlRPChandler");
+	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCblockAllocation", "xmlRPChandler");
+	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCprocessBlockTime", "xmlRPChandler");
 
 	print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, '');
 	xmlrpc_server_destroy($xmlrpc_handle);

Modified: incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php?rev=752583&r1=752582&r2=752583&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php Wed Mar 11 19:09:12 2009
@@ -448,6 +448,294 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn XMLRPCblockAllocation($imageid, $start, $end, $requestcount,
+///                           $usergroupid, $ignoreprivileges)
+///
+/// \param $imageid - id of the image to be used
+/// \param $start - mysql datetime for the start time (i.e. requests should be
+/// prep'd and ready by this time)
+/// \param $end - mysql datetime for the end time
+/// \param $requestcount - number of computers to allocate
+/// \param $usergroupid - id of user group for checking user access to machines
+/// \param $ignoreprivileges (optional, default=0) - 0 (false) or 1 (true) - set
+/// to 1 to select computers from any that are mapped to be able to run the
+/// image; set to 0 to only select computers from ones that are both mapped and
+/// that users in the usergroup assigned to this block request have been granted
+/// access to through the privilege tree
+///
+/// \return an array with blockTimesid as an index with the value of the newly
+/// created block time and at least one other index named 'status' which will
+/// have one of these values\n
+/// \b error - error occurred; there will be 2 additional elements in the array:
+/// \li \b errorcode - error number\n
+/// \li \b errormsg - error string\n
+/// \b success - blockTimesid was processed; there will be two additional
+/// elements in this case:\n
+/// \li \b allocated - total number of desired requests that have been
+/// allocated\n
+/// \li \b unallocated - total number of desired requests that have not been
+/// allocated\n
+/// \b warning - there was a non-fatal issue that occurred while processing
+/// the call; there will be four additional elements in this case:\n
+/// \li \b warningcode - warning number\n
+/// \li \b warningmsg - warning string\n
+/// \li \b allocated - total number of desired requests that have been
+/// allocated\n
+/// \li \b unallocated - total number of desired requests that have not been
+/// allocated\n
+/// note that status may be warning, but allocated may be 0 indicating there
+/// were no errors that occurred, but there simply were not any machines
+/// available\n
+///
+/// \brief creates and processes a block reservation according to the passed
+/// in criteria
+///
+////////////////////////////////////////////////////////////////////////////////
+function XMLRPCblockAllocation($imageid, $start, $end, $requestcount,
+                               $usergroupid, $ignoreprivileges=0) {
+	$ownerid = getUserlistID('vclreload@Local');
+	$name = "API:$start";
+	$managementnodes = getManagementNodes('future');
+	if(empty($managementnodes)) {
+		return array('status' => 'error',
+		             'errorcode' => 12,
+		             'errormsg' => 'could not allocate a management node to handle block allocation');
+	}
+	$mnid = array_rand($managementnodes);
+	$query = "INSERT INTO blockRequest "
+	       .        "(name, "
+	       .        "imageid, "
+	       .        "numMachines, "
+	       .        "groupid, "
+	       .        "repeating, "
+	       .        "ownerid, "
+	       .        "admingroupid, "
+	       .        "managementnodeid, "
+	       .        "expireTime) "
+	       . "VALUES "
+	       .        "('$name', "
+	       .        "$imageid, "
+	       .        "$requestcount, "
+	       .        "$usergroupid, "
+	       .        "'list', "
+	       .        "$ownerid, "
+	       .        "0, "
+	       .        "$mnid, "
+	       .        "'$end')";
+	doQuery($query, 101);
+	$brid = dbLastInsertID();
+	$query = "INSERT INTO blockTimes "
+	       .        "(blockRequestid, "
+	       .        "start, "
+	       .        "end) "
+	       . "VALUES "
+	       .        "($brid, "
+	       .        "'$start', "
+	       .        "'$end')";
+	doQuery($query, 101);
+	$btid = dbLastInsertID();
+	$return = XMLRPCprocessBlockTime($btid, $ignoreprivileges);
+	$return['blockTimesid'] = $btid;
+	return $return;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn XMLRPCprocessBlockTime($blockTimesid, $ignoreprivileges)
+///
+/// \param $blockTimesid - id from the blockTimes table
+/// \param $ignoreprivileges (optional, default=0) - 0 (false) or 1 (true) - set
+/// to 1 to select computers from any that are mapped to be able to run the
+/// image; set to 0 to only select computers from ones that are both mapped and
+/// that users in the usergroup assigned to this block request have been granted
+/// access to through the privilege tree
+///
+/// \return an array with at least one index named 'status' which will have
+/// one of these values\n
+/// \b error - error occurred; there will be 2 additional elements in the array:
+/// \li \b errorcode - error number\n
+/// \li \b errormsg - error string\n
+/// \b completed - blockTimesid was previously successfully processed\n
+/// \b success - blockTimesid was processed; there will be two additional
+/// elements in this case:\n
+/// \li \b allocated - total number of desired requests that have been
+/// allocated\n
+/// \li \b unallocated - total number of desired requests that have not been
+/// allocated\n
+/// \b warning - there was a non-fatal issue that occurred while processing
+/// the call; there will be four additional elements in this case:\n
+/// \li \b warningcode - warning number\n
+/// \li \b warningmsg - warning string\n
+/// \li \b allocated - total number of desired requests that have been
+/// allocated\n
+/// \li \b unallocated - total number of desired requests that have not been
+/// allocated\n
+/// note that status may be warning, but allocated may be 0 indicating there
+/// were no errors that occurred, but there simply were not any machines
+/// available\n
+///
+/// \brief processes a block reservation for the blockTimes entry associated
+/// with blockTimesid
+///
+////////////////////////////////////////////////////////////////////////////////
+function XMLRPCprocessBlockTime($blockTimesid, $ignoreprivileges=0) {
+	global $requestInfo;
+	$return = array('status' => 'success');
+	$query = "SELECT bt.start, "
+	       .        "bt.end, "
+	       .        "br.imageid, "
+	       .        "br.numMachines, "
+	       .        "br.groupid, "
+	       .        "br.expireTime "
+	       . "FROM blockRequest br, "
+	       .      "blockTimes bt "
+	       . "WHERE bt.blockRequestid = br.id AND "
+	       .       "bt.id = $blockTimesid";
+	$qh = doQuery($query, 101);
+	if(! $rqdata = mysql_fetch_assoc($qh)) {
+		return array('status' => 'error',
+		             'errorcode' => 8,
+		             'errormsg' => 'unknown blockTimesid');
+	}
+	if(datetimeToUnix($rqdata['expireTime']) < time()) {
+		return array('status' => 'error',
+		             'errorcode' => 9,
+		             'errormsg' => 'expired block reservation');
+	}
+
+	$images = getImages(0, $rqdata['imageid']);
+	if(empty($images)) {
+		return array('status' => 'error',
+		             'errorcode' => 10,
+		             'errormsg' => 'invalid image associated with block request');
+	}
+
+	# check to see if all computers have been allocated
+	$query = "SELECT COUNT(computerid) AS allocated "
+	       . "FROM blockComputers "
+	       . "WHERE blockTimeid = $blockTimesid";
+	$qh = doQuery($query, 101);
+	if(! $row = mysql_fetch_assoc($qh)) {
+		return array('status' => 'error',
+		             'errorcode' => 15,
+		             'errormsg' => 'failure to communicate with database');
+	}
+	$compCompleted = $row['allocated'];
+	$compsPerRequest = 1 + count($images[$rqdata['imageid']]['subimages']);
+	$toallocate = ($rqdata['numMachines'] * $compsPerRequest) - $compCompleted;
+	if($toallocate == 0)
+		return array('status' => 'completed');
+	$reqToAlloc = $toallocate / $compsPerRequest;
+
+	if(! $ignoreprivileges) {
+		# get userids in user group
+		$tmp = getUserGroupMembers($rqdata['groupid']);
+		if(empty($tmp)) {
+			return array('status' => 'error',
+			             'errorcode' => 11,
+			             'errormsg' => 'empty user group and ignoreprivileges set to 0');
+		}
+		$userids = array_keys($tmp);
+		# make length of $userids match $reqToAlloc by duplicating or trimming some users
+		while($reqToAlloc > count($userids))
+			$userids = array_merge($userids, $userids);
+		if($reqToAlloc < count($userids))
+			$userids = array_splice($userids, 0, $reqToAlloc);
+	}
+
+	# staggering: stagger start times for this round (ie, don't worry about
+	#   previous processing of this block time) such that there is 1 minute
+	#   between the start times for each request
+	$stagExtra = $reqToAlloc * 60;
+
+	# determine estimated load time
+	$imgLoadTime = getImageLoadEstimate($rqdata['imageid']);
+	if($imgLoadTime == 0)
+		$imgLoadTime = $images[$rqdata['imageid']]['reloadtime'] * 60;
+	$loadtime = $imgLoadTime + (10 * 60); # add 10 minute fudge factor
+	$unixstart = datetimeToUnix($rqdata['start']);
+	if((time() + $loadtime + $stagExtra) > $unixstart) {
+		$return['status'] = 'warning';
+		$return['warningcode'] = 13;
+		$return['warningmsg'] = 'possibly insufficient time to load machines';
+	}
+	$start = unixToDatetime($unixstart - $loadtime);
+	$unixend = datetimeToUnix($rqdata['end']);
+
+	$userid = 0;
+	$allocated = 0;
+	$vclreloadid = getUserlistID('vclreload@Local');
+	$revisionid = getProductionRevisionid($rqdata['imageid']);
+	$blockCompVals = array();
+	# FIXME (maybe) - if some subset of users in the user group have available
+	# computers, but others do not, $allocated will be less than the desired
+	# number of machines; however, calling this function enough times will
+	# result in enough machines being allocated because they will continue to be
+	# allocated based on the ones with machines available; this seems like odd
+	# behavior
+	$stagCnt = 0;
+	for($i = 0; $i < $reqToAlloc; $i++) {
+		$stagunixstart = $unixstart - $loadtime - ($stagCnt * 60);
+		$stagstart = unixToDatetime($stagunixstart);
+		if(! $ignoreprivileges)
+			$userid = array_pop($userids);
+		# use end of block time to find available computers, but...
+		$rc = isAvailable($images, $rqdata['imageid'], $stagunixstart,
+		                  $unixend, 0, 0, $userid, $ignoreprivileges);
+		if($rc < 1)
+			continue;
+
+		$stagCnt++;
+
+		$compid = $requestInfo['computers'][0];
+		# ...use start of block time as end of reload reservation
+		$reqid = simpleAddRequest($compid, $rqdata['imageid'], $revisionid,
+		                          $stagstart, $rqdata['start'], 19, $vclreloadid);
+		$allocated++;
+		$blockCompVals[] = "($blockTimesid, $compid, {$rqdata['imageid']})";
+
+		# process any subimages
+		for($key = 1; $key < count($requestInfo['computers']); $key++) {
+			$subimageid = $requestInfo['images'][$key];
+			$subrevid = getProductionRevisionid($subimageid);
+			$compid = $requestInfo['computers'][$key];
+			$mgmtnodeid = $requestInfo['mgmtnodes'][$key];
+			$blockCompVals[] = "($blockTimesid, $compid, $subimageid)";
+
+			$query = "INSERT INTO reservation "
+					 .        "(requestid, "
+					 .        "computerid, "
+					 .        "imageid, "
+					 .        "imagerevisionid, "
+					 .        "managementnodeid) "
+					 . "VALUES "
+					 .       "($reqid, "
+					 .       "$compid, "
+					 .       "$subimageid, "
+					 .       "$subrevid, "
+					 .       "$mgmtnodeid)";
+			doQuery($query, 101);
+		}
+		semUnlock();
+		$blockComps = implode(',', $blockCompVals);
+		$query = "INSERT INTO blockComputers "
+		       .        "(blockTimeid, computerid, imageid) "
+		       . "VALUES $blockComps";
+		doQuery($query, 101);
+		$blockCompVals = array();
+	}
+	if($allocated == 0) {
+		$return['status'] = 'warning';
+		$return['warningcode'] = 14;
+		$return['warningmsg'] = 'unable to allocate any machines';
+	}
+	$return['allocated'] = ($compCompleted / $compsPerRequest) + $allocated;
+	$return['unallocated'] = $rqdata['numMachines'] - $return['allocated'];
+	return $return;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn XMLRPCtest($string)
 ///
 /// \param $string - a string



Mime
View raw message