You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2011/04/29 17:34:23 UTC

svn commit: r1097842 [4/4] - in /incubator/vcl/trunk/web: .ht-inc/ css/ js/

Modified: incubator/vcl/trunk/web/.ht-inc/utils.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=1097842&r1=1097841&r2=1097842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/utils.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/utils.php Fri Apr 29 15:34:22 2011
@@ -294,6 +294,9 @@ function initGlobals() {
 		case 'dashboard':
 			require_once(".ht-inc/dashboard.php");
 			break;
+		case 'serverProfiles':
+			require_once(".ht-inc/serverprofiles.php");
+			break;
 		default:
 			require_once(".ht-inc/requests.php");
 	}
@@ -1098,6 +1101,7 @@ function getOSList() {
 /// \b platform - platform the image is for\n
 /// \b osid - osid for the os on the image\n
 /// \b os - os the image contains\n
+/// \b installtype - method used to install image\n
 /// \b minram - minimum amount of RAM needed for image\n
 /// \b minprocnumber - minimum number of processors needed for image\n
 /// \b minprocspeed - minimum speed of processor(s) needed for image\n
@@ -1118,6 +1122,7 @@ function getOSList() {
 /// \b usergroupid - id of user group to use when creating local accounts\n
 /// \b usergroup - user group to use when creating local accounts\n
 /// \b sysprep - whether or not to use sysprep on creation of the image\n
+/// \b connectmethods - array of enabled connect methods\n
 /// \b subimages - an array of subimages to be loaded along with selected
 /// image\n
 /// \b imagerevision - an array of revision info about the image, it has these
@@ -1137,6 +1142,7 @@ function getImages($includedeleted=0, $i
 	       .        "p.name AS platform, "
 	       .        "i.OSid AS osid, "
 	       .        "o.name AS os, "
+	       .        "o.installtype, "
 	       .        "i.minram AS minram, "
 	       .        "i.minprocnumber AS minprocnumber, "
 	       .        "i.minprocspeed AS minprocspeed, "
@@ -1227,6 +1233,7 @@ function getImages($includedeleted=0, $i
 		$qh3 = doQuery($query3, 101);
 		while($row3 = mysql_fetch_assoc($qh3))
 			$imagelist[$row['id']]['imagerevision'][$row3['id']] = $row3;
+		$imagelist[$row['id']]['connectmethods'] = getImageConnectMethods($row['id']);
 	}
 	return $imagelist;
 }
@@ -1309,6 +1316,48 @@ function getImageNotes($imageid) {
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn getImageConnectMethods($imageid)
+///
+/// \param $imageid - id of an image
+///
+/// \return an array of connect methods enabled for specified image where the
+/// key is the id of the connect method and the value is the description
+///
+/// \brief builds an array of connect methods enabled for the image
+///
+////////////////////////////////////////////////////////////////////////////////
+function getImageConnectMethods($imageid) {
+	$query = "SELECT c.id, "
+	       .        "c.description, "
+	       .        "cm.disabled "
+	       . "FROM connectmethod c, "
+	       .      "connectmethodmap cm, "
+	       .      "image i "
+	       . "LEFT JOIN OS o ON (o.id = i.OSid) "
+	       . "LEFT JOIN OStype ot ON (ot.name = o.type) "
+	       . "WHERE i.id = $imageid AND "
+	       .       "cm.connectmethodid = c.id AND "
+	       .       "cm.autoprovisioned IS NULL AND "
+	       .       "(cm.OStypeid = ot.id OR "
+	       .        "cm.OSid = o.id OR "
+	       .        "cm.imageid = $imageid) "
+	       . "ORDER BY cm.disabled, "
+	       .          "c.description";
+	$methods = array();
+	$qh = doQuery($query, 101);
+	while($row = mysql_fetch_assoc($qh)) {
+		if($row['disabled']) {
+		  if(array_key_exists($row['id'], $methods))
+			unset($methods[$row['id']]);
+		}
+		else
+			$methods[$row['id']] = $row['description'];
+	}
+	return $methods;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn checkClearImageMeta($imagemetaid, $imageid, $ignorefield)
 ///
 /// \param $imagemetaid - id from imagemeta table
@@ -1799,6 +1848,8 @@ function addOwnedResources(&$resources, 
 			$field = "name";
 		elseif($type == "managementnode")
 			$field = "hostname";
+		elseif($type == "serverprofile")
+			$field = "name";
 		else
 			continue;
 		$query = "SELECT id, "
@@ -1872,6 +1923,8 @@ function getResourcesFromGroups($groups,
 		$field = "name";
 	elseif($type == "managementnode")
 		$field = "hostname";
+	elseif($type == "serverprofile")
+		$field = "name";
 	else
 		return array();
 
@@ -3172,6 +3225,8 @@ function getUsersGroupPerms($usergroupid
 	if(empty($usergroupids))
 		return array();
 	$inlist = implode(',', $usergroupids);
+	if($inlist == '')
+		return array();
 	$query = "SELECT DISTINCT t.id, "
 	       .        "t.name "
 	       . "FROM usergroupprivtype t, "
@@ -3268,7 +3323,7 @@ function updateUserData($id, $type="logi
 ///
 /// \param $loginid - a login id
 ///
-/// \return id from userlist table for the user, NULL if userid not in table
+/// \return id from user table for the user, NULL if userid not in table
 ///
 /// \brief looks up the user via LDAP and adds to DB
 ///
@@ -3497,6 +3552,7 @@ function isAvailable($images, $imageid, 
 		$requestData = getRequestInfo($requestid);
 	$startstamp = unixToDatetime($start);
 	$endstamp = unixToDatetime($end + 900);
+	$vmhostcheckdone = 0;
 	foreach($requestInfo["images"] as $key => $imageid) {
 		# check for max concurrent usage of image
 		if($images[$imageid]['maxconcurrent'] != NULL) {
@@ -3563,6 +3619,8 @@ function isAvailable($images, $imageid, 
 				semUnlock();
 				return 0;
 			}
+			// set $virtual to 0 so that it is defined later but skips the additional code
+			$virtual = 0;
 		}
 		// otherwise, build a list of computers
 		else {
@@ -3628,7 +3686,7 @@ function isAvailable($images, $imageid, 
 			       .       "c.id NOT IN ($alloccompids) "
 			       . "ORDER BY (c.procspeed * c.procnumber) DESC, "
 			       .          "RAM DESC, "
-					 .          "network DESC";
+			       .          "network DESC";
 
 			$qh = doQuery($query, 129);
 			while($row = mysql_fetch_assoc($qh)) {
@@ -3662,6 +3720,12 @@ function isAvailable($images, $imageid, 
 		$currentids = array_diff($currentids, $usedComputerids);
 		$blockids = array_diff($blockids, $usedComputerids);
 
+		// if modifying a reservation and $computerids is now empty, return 0
+		if($requestid && empty($computerids)) {
+			semUnlock();
+			return 0;
+		}
+
 		# remove computers from list that are allocated to block allocations
 		if($altRemoveBlockCheck) {
 			if(editRequestBlockCheck($computerids[0], $imageid, $start, $end)) {
@@ -3681,24 +3745,30 @@ function isAvailable($images, $imageid, 
 			#   available because they would already fit within the host's available
 			#   RAM
 
-			$query = "CREATE TEMPORARY TABLE VMhostCheck ( "
-			       .    "RAM mediumint unsigned NOT NULL, "
-			       .    "allocRAM mediumint unsigned NOT NULL, "
-			       .    "vmhostid smallint unsigned NOT NULL "
-			       . ") ENGINE=MEMORY";
-			doQuery($query, 101);
-
-			$query = "INSERT INTO VMhostCheck "
-			       . "SELECT c.RAM, "
-			       .        "SUM(i.minram), "
-			       .        "v.id "
-			       . "FROM vmhost v "
-			       . "LEFT JOIN computer c ON (v.computerid = c.id) "
-			       . "LEFT JOIN computer c2 ON (v.id = c2.vmhostid) "
-			       . "LEFT JOIN image i ON (c2.currentimageid = i.id) "
-			       . "WHERE c.stateid = 20 "
-			       . "GROUP BY c.id";
-			doQuery($query, 101);
+			if(! $vmhostcheckdone) {
+				$vmhostcheckdone = 1;
+				$query = "DROP TEMPORARY TABLE IF EXISTS VMhostCheck";
+				doQuery($query, 101);
+
+				$query = "CREATE TEMPORARY TABLE VMhostCheck ( "
+				       .    "RAM mediumint unsigned NOT NULL, "
+				       .    "allocRAM mediumint unsigned NOT NULL, "
+				       .    "vmhostid smallint unsigned NOT NULL "
+				       . ") ENGINE=MEMORY";
+				doQuery($query, 101);
+
+				$query = "INSERT INTO VMhostCheck "
+				       . "SELECT c.RAM, "
+				       .        "SUM(i.minram), "
+				       .        "v.id "
+				       . "FROM vmhost v "
+				       . "LEFT JOIN computer c ON (v.computerid = c.id) "
+				       . "LEFT JOIN computer c2 ON (v.id = c2.vmhostid) "
+				       . "LEFT JOIN image i ON (c2.currentimageid = i.id) "
+				       . "WHERE c.stateid = 20 "
+				       . "GROUP BY c.id";
+				doQuery($query, 101);
+			}
 
 			$inids = implode(',', $computerids);
 			// if want overbooking, modify the last part of the WHERE clause
@@ -3767,9 +3837,10 @@ function schCheckMaintenance($start, $en
 	$enddt = unixToDatetime($end);
 	$query = "SELECT id "
 	       . "FROM sitemaintenance "
-			 . "WHERE (allowreservations = 0 AND "
-			 .       "(('$enddt' > start) AND ('$startdt' < end))) OR "
-	       .       "(('$startdt' > (start - INTERVAL 30 MINUTE)) AND ('$startdt' < end))";
+	       . "WHERE ((allowreservations = 0 AND "
+	       .       "(('$enddt' > start) AND ('$startdt' < end))) OR "
+	       .       "(('$startdt' > (start - INTERVAL 30 MINUTE)) AND ('$startdt' < end))) AND "
+	       .       "end > NOW()";
 	$qh = doQuery($query, 101);
 	if($row = mysql_fetch_row($qh))
 		return true;
@@ -4147,18 +4218,18 @@ function addRequest($forimaging=0, $revi
 	       .        "laststateid, "
 	       .        "logid, "
 	       .        "forimaging, "
-			 .        "start, "
-			 .        "end, "
-			 .        "daterequested) "
+	       .        "start, "
+	       .        "end, "
+	       .        "daterequested) "
 	       . "VALUES "
 	       .       "(13, "
 	       .       "{$user['id']}, "
 	       .       "13, "
 	       .       "$logid, "
 	       .       "$forimaging, "
-			 .       "'$startstamp', "
-			 .       "'$endstamp', "
-			 .       "NOW())";
+	       .       "'$startstamp', "
+	       .       "'$endstamp', "
+	       .       "NOW())";
 	$qh = doQuery($query, 136);
 
 	$qh = doQuery("SELECT LAST_INSERT_ID() FROM request", 134);
@@ -4187,17 +4258,17 @@ function addRequest($forimaging=0, $revi
 		$mgmtnodeid = $requestInfo['mgmtnodes'][$key];
 
 		$query = "INSERT INTO reservation "
-				 .        "(requestid, "
-				 .        "computerid, "
-				 .        "imageid, "
-				 .        "imagerevisionid, "
-				 .        "managementnodeid) "
-				 . "VALUES "
-				 .       "($requestid, "
-				 .       "$computerid, "
-				 .       "$imageid, "
-				 .       "$imagerevisionid, "
-				 .       "$mgmtnodeid)";
+		       .        "(requestid, "
+		       .        "computerid, "
+		       .        "imageid, "
+		       .        "imagerevisionid, "
+		       .        "managementnodeid) "
+		       . "VALUES "
+		       .       "($requestid, "
+		       .       "$computerid, "
+		       .       "$imageid, "
+		       .       "$imagerevisionid, "
+		       .       "$mgmtnodeid)";
 		doQuery($query, 133);
 		addSublogEntry($logid, $imageid, $imagerevisionid, $computerid, $mgmtnodeid);
 	}
@@ -4235,16 +4306,16 @@ function simpleAddRequest($compid, $imag
 	       .        "(stateid, "
 	       .        "userid, "
 	       .        "laststateid, "
-			 .        "start, "
-			 .        "end, "
-			 .        "daterequested) "
+	       .        "start, "
+	       .        "end, "
+	       .        "daterequested) "
 	       . "VALUES "
 	       .       "($stateid, "
 	       .       "$userid, "
 	       .       "$stateid, "
-			 .       "'$start', "
-			 .       "'$end', "
-			 .       "NOW())";
+	       .       "'$start', "
+	       .       "'$end', "
+	       .       "NOW())";
 	doQuery($query, 101);
 
 	$requestid = dbLastInsertID();
@@ -4253,17 +4324,17 @@ function simpleAddRequest($compid, $imag
 
 	# add an entry to the reservation table for each image
 	$query = "INSERT INTO reservation "
-			 .        "(requestid, "
-			 .        "computerid, "
-			 .        "imageid, "
-			 .        "imagerevisionid, "
-			 .        "managementnodeid) "
-			 . "VALUES "
-			 .       "($requestid, "
-			 .       "$compid, "
-			 .       "$imageid, "
-			 .       "$revisionid, "
-			 .       "$mgmtnodeid)";
+	       .        "(requestid, "
+	       .        "computerid, "
+	       .        "imageid, "
+	       .        "imagerevisionid, "
+	       .        "managementnodeid) "
+	       . "VALUES "
+	       .       "($requestid, "
+	       .       "$compid, "
+	       .       "$imageid, "
+	       .       "$revisionid, "
+	       .       "$mgmtnodeid)";
 	doQuery($query, 101);
 	$testid = dbLastInsertID();
 	if($testid == 0)
@@ -4321,9 +4392,11 @@ function findManagementNode($compid, $st
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getRequestInfo($id)
+/// \fn getRequestInfo($id, $returnNULL)
 ///
 /// \param $id - id of request
+/// \param $returnNULL - (optional, default=0) return NULL if reservation no
+///                      longer exists
 ///
 /// \return an array containing the following elements:\n
 /// \b stateid - stateid of the request\n
@@ -4336,7 +4409,8 @@ function findManagementNode($compid, $st
 /// \b id - id of this request\n
 /// \b logid - id from log table\n
 /// \b test - test flag\n
-/// \b forimaging - 0 if request is normal, 1 if it is for imaging\n\n
+/// \b forimaging - 0 if request is normal, 1 if it is for imaging\n
+/// \b serverrequest - 0 if request is normal, 1 if it is a server request\n\n
 /// an array of reservations associated with the request whose key is
 /// 'reservations', each with the following items:\n
 /// \b imageid - id of the image\n
@@ -4356,7 +4430,7 @@ function findManagementNode($compid, $st
 /// \brief creates an array with info about request $id
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function getRequestInfo($id) {
+function getRequestInfo($id, $returnNULL=0) {
 	global $printedHTMLheader, $HTMLheader;
 	if(empty($id))
 		abort(9);
@@ -4374,6 +4448,8 @@ function getRequestInfo($id) {
 	       . "WHERE id = $id";
 	$qh = doQuery($query, 165);
 	if(! ($data = mysql_fetch_assoc($qh))) {
+		if($returnNULL)
+			return NULL;
 		# FIXME handle XMLRPC cases
 		if(! $printedHTMLheader) 
 			print $HTMLheader;
@@ -4415,9 +4491,14 @@ function getRequestInfo($id) {
 	       . "ORDER BY rs.id";
 	$qh = doQuery($query, 101);
 	$data["reservations"] = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysql_fetch_assoc($qh))
 		array_push($data["reservations"], $row);
-	}
+	$query = "SELECT id FROM serverrequest WHERE requestid = $id";
+	$qh = doQuery($query, 101);
+	if(mysql_num_rows($qh))
+		$data['serverrequest'] = 1;
+	else
+		$data['serverrequest'] = 0;
 	return $data;
 }
 
@@ -4563,11 +4644,16 @@ function deleteRequest($request) {
 		return;
 	}
 
-	$query = "DELETE FROM request WHERE id = " . $request["id"];
-	$qh = doQuery($query, 152);
+	if($request['serverrequest']) {
+		$query = "DELETE FROM serverrequest WHERE requestid = {$request["id"]}";
+		$qh = doQuery($query, 152);
+	}
+
+	$query = "DELETE FROM request WHERE id = {$request["id"]}";
+	$qh = doQuery($query, 153);
 
 	$query = "DELETE FROM reservation WHERE requestid = {$request["id"]}";
-	doQuery($query, 153);
+	doQuery($query, 154);
 
 	addChangeLogEntry($request["logid"], NULL, NULL, NULL, NULL, "deleted");
 }
@@ -4626,7 +4712,7 @@ function moveReservationsOffComputer($co
 	       .       "rs.requestid = rq.id AND "
 	       .       "rq.start > '$checkstart' AND "
 	       .       "rq.stateid NOT IN (1, 5, 11, 12) "
-			 . "ORDER BY rq.start";
+	       . "ORDER BY rq.start";
 	if($count)
 		$query .= " LIMIT $count";
 	$qh = doQuery($query, 101);
@@ -4687,6 +4773,7 @@ function moveReservationsOffComputer($co
 /// \return an array of user's requests; the array has the following elements
 /// for each entry where forcheckout == 1 for the image:\n
 /// \b id - id of the request\n
+/// \b userid - id of user owning request\n
 /// \b imageid - id of requested image\n
 /// \b imagerevisionid - revision id of requested image\n
 /// \b image - name of requested image\n
@@ -4701,12 +4788,25 @@ function moveReservationsOffComputer($co
 /// \b forcheckout - 1 if image is available for reservations, 0 if not\n
 /// \b test - test flag - 0 or 1\n
 /// \b longterm - 1 if request length is > 24 hours\n
+/// \b server - 1 if corresponding entry in serverprofiles\n
+/// \b serverowner - 1 user owns the reservation, 0 if not\n
 /// \b resid - id of primary reservation\n
 /// \b compimageid - currentimageid for primary computer\n
 /// \b computerstateid - current stateid of primary computer\n
 /// \b computerid - id of primary computer\n
 /// \b IPaddress - IP address of primary computer\n
 /// \b comptype - type of primary computer\n
+/// \b vmhostid - if VM, id of host's entry in vmhost table, NULL otherwise\n
+/// the following additional items if a server request (values will be NULL
+/// if not a server request), some values can be NULL:\n
+/// \b serverrequestid - from server request table\n
+/// \b fixedIP - if specified for request\n
+/// \b fixedMAC - if specified for request\n
+/// \b serveradmingroupid - id of admin user group\n
+/// \b serveradmingroup - name of admin user group\n
+/// \b serverlogingroupid - id of login user group\n
+/// \b serverlogingroup - name of login user group\n
+/// \b monitored - whether or not request is to be monitored (0 or 1)\n
 /// and an array of subimages named reservations with the following elements
 /// for each subimage:\n
 /// \b resid - id of reservation\n
@@ -4726,12 +4826,13 @@ function moveReservationsOffComputer($co
 ////////////////////////////////////////////////////////////////////////////////
 function getUserRequests($type, $id=0) {
 	global $user;
-	if($id == 0) {
+	if($id == 0)
 		$id = $user["id"];
-	}
+	$ingroupids = implode(',', array_keys($user['groups']));
 	$query = "SELECT i.name AS image, "
 	       .        "i.prettyname AS prettyimage, "
 	       .        "i.id AS imageid, "
+	       .        "rq.userid, "
 	       .        "rq.start, "
 	       .        "rq.end, "
 	       .        "rq.daterequested, "
@@ -4745,17 +4846,33 @@ function getUserRequests($type, $id=0) {
 	       .        "c.stateid AS computerstateid, "
 	       .        "c.IPaddress, "
 	       .        "c.type AS comptype, "
+	       .        "c.vmhostid, "
 	       .        "rq.forimaging, "
 	       .        "i.forcheckout, "
 	       .        "rs.managementnodeid, "
 	       .        "rs.imagerevisionid, "
-	       .        "rq.test "
-	       . "FROM request rq, "
-	       .      "reservation rs, "
+	       .        "rq.test,"
+	       .        "sp.requestid AS serverrequestid, "
+	       .        "sp.fixedIP, "
+	       .        "sp.fixedMAC, "
+	       .        "sp.admingroupid AS serveradmingroupid, "
+	       .        "uga.name AS serveradmingroup, "
+	       .        "sp.logingroupid AS serverlogingroupid, "
+	       .        "ugl.name AS serverlogingroup, "
+	       .        "sp.monitored, "
+	       .        "(UNIX_TIMESTAMP(l.initialend) - UNIX_TIMESTAMP(l.start)) AS initialduration "
+	       . "FROM reservation rs, "
 	       .      "image i, "
 	       .      "OS o, "
-	       .      "computer c "
-	       . "WHERE rq.userid = $id AND "
+	       .      "computer c, "
+	       .      "request rq "
+	       . "LEFT JOIN serverrequest sp ON (sp.requestid = rq.id) "
+	       . "LEFT JOIN usergroup uga ON (uga.id = sp.admingroupid) "
+	       . "LEFT JOIN usergroup ugl ON (ugl.id = sp.logingroupid) "
+	       . "LEFT JOIN log l ON (l.requestid = rq.id) "
+	       . "WHERE (rq.userid = $id OR "
+	       .       "sp.admingroupid IN ($ingroupids) OR "
+	       .       "sp.logingroupid IN ($ingroupids)) AND "
 	       .       "rs.requestid = rq.id AND "
 	       .       "rs.imageid = i.id AND "
 	       .       "rq.end > NOW() AND "
@@ -4765,9 +4882,13 @@ function getUserRequests($type, $id=0) {
 	       .       "rq.laststateid NOT IN (1, 10, 16, 17) ";  # deleted, maintenance, complete, image, makeproduction
 	if($type == "normal")
 		$query .=   "AND rq.forimaging = 0 "
-		       .    "AND i.forcheckout = 1 ";
+		       .    "AND i.forcheckout = 1 "
+		       .    "AND sp.requestid IS NULL ";
 	if($type == "forimaging")
-		$query .=   "AND rq.forimaging = 1 ";
+		$query .=   "AND rq.forimaging = 1 "
+		       .    "AND sp.requestid IS NULL ";
+	if($type == "server")
+		$query .=   "AND sp.requestid IS NOT NULL ";
 	$query .= "ORDER BY rq.start, "
 	       .           "rs.id";
 
@@ -4800,10 +4921,34 @@ function getUserRequests($type, $id=0) {
 			continue;
 		$foundids[$row['id']] = 1;
 		$data[$count] = $row;
-		if((datetimeToUnix($row['end']) - datetimeToUnix($row['start'])) > SECINDAY)
+		if(! is_null($row['serverrequestid'])) {
+			$data[$count]['server'] = 1;
+			$data[$count]['longterm'] = 0;
+			if($row['userid'] == $user['id']) {
+				$data[$count]['serverowner'] = 1;
+				$data[$count]['serveradmin'] = 1;
+			}
+			else {
+				$data[$count]['serverowner'] = 0;
+				if(! empty($row['serveradmingroupid']) && 
+				   array_key_exists($row['serveradmingroupid'], $user['groups']))
+					$data[$count]['serveradmin'] = 1;
+				else
+					$data[$count]['serveradmin'] = 0;
+			}
+		}
+		elseif((datetimeToUnix($row['end']) - datetimeToUnix($row['start'])) > SECINDAY) {
+			$data[$count]['server'] = 0;
 			$data[$count]['longterm'] = 1;
-		else
+			$data[$count]['serverowner'] = 1;
+			$data[$count]['serveradmin'] = 1;
+		}
+		else {
+			$data[$count]['server'] = 0;
 			$data[$count]['longterm'] = 0;
+			$data[$count]['serverowner'] = 1;
+			$data[$count]['serveradmin'] = 1;
+		}
 		$data[$count]["reservations"] = array();
 		$query2 = sprintf($qbase2, $row['resid'], $row['id']);
 		$qh2 = doQuery($query2, 160);
@@ -5933,7 +6078,16 @@ function showTimeTable($links) {
 				else {
 					$title = "User: " . $timeslots[$id][$stamp]["unityid"]
 					       . " Image: " . $timeslots[$id][$stamp]["prettyimage"];
-					$cdata = array('requestid' => $timeslots[$id][$stamp]["requestid"]);
+					$ttdata = array('start' => $argstart,
+					                'end' => $argend,
+					                'imageid' => $imageid,
+					                'requestid' => $timeslots[$id][$stamp]["requestid"],
+					                'length' => $length,
+					                'platforms' => $platforms,
+					                'schedules' => $schedules,
+					                'imaging' => $imaging);
+					$cdata = array('requestid' => $timeslots[$id][$stamp]["requestid"],
+					               'ttdata' => $ttdata);
 					$cont = addContinuationsEntry('viewRequestInfo', $cdata);
 					print "          <TD bgcolor=\"#ff0000\"><a href=\"" . BASEURL;
 					print SCRIPT . "?continuation=$cont\"><img src=images/red.jpg ";
@@ -6724,6 +6878,8 @@ function requestIsReady($request) {
 	   $request["computerstateid"] == 3) ||   //   computer reserved
 	   ($request["currstateid"] == 8 &&       // request current state inuse
 	   $request["computerstateid"] == 8) ||   //   and computer state inuse
+	   ($request["currstateid"] == 24 &&       // request current state checkpoint
+	   $request["computerstateid"] == 8) ||   //   and computer state inuse
 	   ($request["currstateid"] == 14 &&      // request current state pending
 	   $request["laststateid"] == 8 &&        //   and last state inuse and
 	   $request["computerstateid"] == 8) ||   //   computer inuse
@@ -6779,9 +6935,10 @@ function printArray($array) {
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn prettyDatetime($stamp)
+/// \fn prettyDatetime($stamp, $showyear=0)
 ///
 /// \param $stamp - a timestamp in unix or mysql datetime format
+/// \param $showyear (optional, default=0) - set to 1 to include year
 ///
 /// \return date/time in html format of [Day of week], [month] [day of month],
 /// [HH:MM] [am/pm]
@@ -6789,12 +6946,18 @@ function printArray($array) {
 /// \brief reformats the datetime to look better
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function prettyDatetime($stamp) {
+function prettyDatetime($stamp, $showyear=0) {
 	if(preg_match('/^[\d]+$/', $stamp)) {
-		$return = date('l, M#jS, g:i a', $stamp);
+		if($showyear)
+			$return = date('l, M#jS,#Y, g:i a', $stamp);
+		else
+			$return = date('l, M#jS, g:i a', $stamp);
 	}
 	else {
-		$return = date('l, M#jS, g:i a', datetimeToUnix($stamp));
+		if($showyear)
+			$return = date('l, M#jS,#Y, g:i a', datetimeToUnix($stamp));
+		else
+			$return = date('l, M#jS, g:i a', datetimeToUnix($stamp));
 	}
 	$return = str_replace('#', '&nbsp;', $return);
 	return $return;
@@ -7812,6 +7975,43 @@ function getResourceMapping($resourcetyp
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn getConnectMethods()
+///
+/// \param $imageid - id of image for which to get available methods
+///
+/// \return an array of connect methods where the key is the id and the value is
+/// an array with these items:\n
+/// \b description - description of method\n
+/// \b autoprovisioned - 0 or 1, whether or not the method can be automatically
+/// provisioned by the backend
+///
+/// \brief get the available connection methods for a specific image
+///
+////////////////////////////////////////////////////////////////////////////////
+function getConnectMethods() {
+	$query = "SELECT DISTINCT c.id, "
+	       .        "c.description, "
+	       .        "cm.autoprovisioned "
+	       . "FROM connectmethod c, "
+	       .      "connectmethodmap cm, "
+	       .      "image i "
+	       . "LEFT JOIN OS o ON (o.id = i.OSid) "
+	       . "LEFT JOIN OStype ot ON (ot.name = o.type) "
+	       . "WHERE i.id = $imageid AND "
+	       .       "cm.connectmethodid = c.id AND "
+	       .       "cm.autoprovisioned IS NOT NULL AND "
+	       .       "(cm.OStypeid = ot.id OR "
+	       .        "cm.OSid = o.id) "
+	       . "ORDER BY c.description";
+	$methods = array();
+	$qh = doQuery($query, 101);
+	while($row = mysql_fetch_assoc($qh))
+		$methods[$row['id']] = $row;
+	return $methods;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn timeToNextReservation($request)
 ///
 /// \param $request - either a request id or an array returned from
@@ -8347,6 +8547,7 @@ function xmlrpccall() {
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetUserGroupMembers", "xmlRPChandler");
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddUsersToGroup", "xmlRPChandler");
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveUsersFromGroup", "xmlRPChandler");
+	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCautoCapture", "xmlRPChandler");
 
 	print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, '');
 	xmlrpc_server_destroy($xmlrpc_handle);
@@ -8802,7 +9003,7 @@ function sendHeaders() {
 					print "</head>\n";
 					print "<body>\n";
 					print "Logging out of VCL...";
-					print "<iframe src=\"http://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
+					print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
 					print "</iframe>\n";
 					if(array_key_exists('Shib-Identity-Provider', $shibdata) &&
 					   ! empty($shibdata['Shib-Identity-Provider'])) {
@@ -8967,6 +9168,11 @@ function getNavMenu($inclogout, $inchome
 		$rt .= "<a href=\"" . BASEURL . SCRIPT;
 		$rt .= "?mode=selectMgmtnodeOption\">Management Nodes</a></li>\n";
 	}
+	if(in_array("serverProfileAdmin", $user["privileges"])) {
+		$rt .= menulistLI('serverProfiles');
+		$rt .= "<a href=\"" . BASEURL . SCRIPT;
+		$rt .= "?mode=serverProfiles\">Server Profiles</a></li>\n";
+	}
 	if(count($computermetadata["platforms"]) &&
 		count($computermetadata["schedules"])) {
 		$rt .= menulistLI('timeTable');
@@ -9079,12 +9285,39 @@ function getDojoHTML($refresh) {
 		case 'createSelectImage':
 		case 'submitCreateImage':
 			$dojoRequires = array('dojo.parser',
+			                      'dijit.form.DateTextBox',
+			                      'dijit.form.TimeTextBox',
+			                      'dojox.string.sprintf',
 			                      'dijit.form.FilteringSelect');
 			break;
 		case 'viewRequests':
 			$dojoRequires = array('dojo.parser',
+			                      'dijit.form.DateTextBox',
+			                      'dijit.form.TimeTextBox',
+			                      'dijit.form.Select',
+			                      'dojox.string.sprintf',
+			                      'dijit.Dialog',
+			                      'dijit.Menu',
+			                      'dijit.form.Button',
+			                      'dijit.form.DropDownButton',
+			                      'dijit.Tooltip',
+			                      'vcldojo.HoverTooltip',
 			                      'dojox.layout.FloatingPane');
 			break;
+		case 'viewRequestInfo':
+			$dojoRequires = array('dojo.parser',
+			                      #'dijit.form.DateTextBox',
+			                      #'dijit.form.TimeTextBox',
+			                      #'dijit.form.Select',
+			                      #'dojox.string.sprintf',
+			                      'dijit.Dialog',
+			                      #'dijit.Menu',
+			                      'dijit.form.Button',
+			                      #'dijit.form.DropDownButton',
+			                      #'dijit.Tooltip',
+			                      #'vcldojo.HoverTooltip',
+										 /*'dojox.layout.FloatingPane'*/);
+			break;
 		case 'blockAllocations':
 			$dojoRequires = array('dojo.parser',
 			                      'dijit.form.Button',
@@ -9164,9 +9397,15 @@ function getDojoHTML($refresh) {
 			                      'dijit.form.Textarea',
 			                      'dijit.form.DropDownButton',
 			                      'dijit.form.FilteringSelect',
+			                      'dijit.form.Select',
 			                      'dijit.form.Button',
 			                      'dijit.Dialog',
-			                      'dijit.TitlePane');
+			                      'dijit.TitlePane',
+			                      'dojo.data.ItemFileWriteStore');
+			break;
+		case 'startCheckpoint':
+			$dojoRequires = array('dojo.parser',
+			                      'dijit.form.Textarea');
 			break;
 		case 'selectComputers':
 		case 'viewComputerGroups':
@@ -9192,6 +9431,25 @@ function getDojoHTML($refresh) {
 			                      'dijit.Tooltip',
 			                      'dijit.form.NumberSpinner');
 			break;
+		case 'serverProfiles':
+			$dojoRequires = array('dojo.parser',
+			                      'dijit.Dialog',
+			                      'dijit.form.DateTextBox',
+			                      'dijit.form.TimeTextBox',
+			                      'dijit.form.Button',
+			                      'dijit.form.FilteringSelect',
+			                      'dijit.form.Select',
+			                      'dijit.layout.LinkPane',
+			                      #'dijit.TitlePane',
+			                      'dijit.form.TextBox',
+			                      'dijit.form.ValidationTextBox',
+			                      'dijit.form.CheckBox',
+			                      'dijit.form.Textarea',
+			                      'dijit.layout.ContentPane',
+			                      'dijit.layout.TabContainer',
+			                      'dojox.string.sprintf',
+			                      'dojo.data.ItemFileWriteStore');
+			break;
 		case 'selectauth':
 			$dojoRequires = array('dojo.parser');
 			break;
@@ -9254,6 +9512,7 @@ function getDojoHTML($refresh) {
 			$rt .= "</script>\n";
 			$rt .= "<script type=\"text/javascript\">\n";
 			$rt .= "   dojo.addOnLoad(function() {\n";
+			$rt .= "   dojo.registerModulePath(\"vcldojo\", \"../../js/vcldojo\");\n";
 			foreach($dojoRequires as $req) {
 				$rt .= "   dojo.require(\"$req\");\n";
 			}
@@ -9270,6 +9529,7 @@ function getDojoHTML($refresh) {
 		case 'submitRequest':
 		case 'createSelectImage':
 		case 'submitCreateImage':
+		case 'viewRequestInfo':
 			$rt .= "<style type=\"text/css\">\n";
 			$rt .= "   @import \"themes/$skin/css/dojo/$skin.css\";\n";
 			#$rt .= "   @import \"dojo/dojo/resources/dojo.css\";\n";
@@ -9487,6 +9747,26 @@ function getDojoHTML($refresh) {
 			$rt .= "<script type=\"text/javascript\" src=\"js/managementnodes.js\"></script>\n";
 			return $rt;
 
+		case "serverProfiles":
+			$rt .= "<style type=\"text/css\">\n";
+			$rt .= "   @import \"themes/$skin/css/dojo/$skin.css\";\n";
+			#$rt .= "   @import \"css/dashboard.css\";\n";
+			$rt .= "</style>\n";
+			$rt .= "<script type=\"text/javascript\" src=\"js/serverprofiles.js\"></script>\n";
+			$rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n";
+			$rt .= "   djConfig=\"parseOnLoad: true, debug: true\">\n";
+			$rt .= "</script>\n";
+			$rt .= "<script type=\"text/javascript\">\n";
+			foreach($dojoRequires as $req)
+				$rt .= "   dojo.require(\"$req\");\n";
+			#$rt .= "   dojo.addOnLoad(function() {\n";
+			#$rt .= "   });\n";
+			$rt .= "   dojo.addOnLoad(getProfiles);\n";
+			$cont = addContinuationsEntry('AJserverProfileStoreData', array(), 120, 1, 0);
+			$rt .= "   dojo.addOnLoad(function() {populateProfileStore('$cont');});\n";
+			$rt .= "</script>\n";
+			return $rt;
+
 		case "selectComputers":
 		case "viewComputerGroups":
 		case "submitComputerGroups":

Modified: incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php?rev=1097842&r1=1097841&r2=1097842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/xmlrpcWrappers.php Fri Apr 29 15:34:22 2011
@@ -1015,7 +1015,10 @@ function XMLRPCprocessBlockTime($blockTi
 		             'errormsg' => 'failure to communicate with database');
 	}
 	$compCompleted = $row['allocated'];
-	$compsPerAlloc = 1 + count($images[$rqdata['imageid']]['subimages']);
+	if(array_key_exists('subimages', $images[$rqdata['imageid']]))
+		$compsPerAlloc = 1 + count($images[$rqdata['imageid']]['subimages']);
+	else
+		$compsPerAlloc = 1;
 	$toallocate = ($rqdata['numMachines'] * $compsPerAlloc) - $compCompleted;
 	if($toallocate == 0)
 		return array('status' => 'completed');
@@ -1715,6 +1718,100 @@ function XMLRPCremoveUsersFromGroup($nam
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn XMLRPCautoCapture($requestid)
+///
+/// \param $requestid - id of request to be captured
+///
+/// \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
+/// \li \b errormsg - error string
+///
+/// \b success - image was successfully set to be captured
+///
+/// \brief creates entries in appropriate tables to capture an image and sets
+/// the request state to image
+///
+////////////////////////////////////////////////////////////////////////////////
+function XMLRPCautoCapture($requestid) {
+	global $user, $xmlrpcBlockAPIUsers;
+	if(! in_array($user['id'], $xmlrpcBlockAPIUsers)) {
+		return array('status' => 'error',
+		             'errorcode' => 47,
+		             'errormsg' => 'access denied to XMLRPCautoCapture');
+	}
+	$query = "SELECT id FROM request WHERE id = $requestid";
+	$qh = doQuery($query, 101);
+	if(! mysql_num_rows($qh)) {
+		return array('status' => 'error',
+		             'errorcode' => 52,
+		             'errormsg' => 'specified request does not exist');
+	}
+	$reqData = getRequestInfo($requestid);
+	# check state of reservation
+	if($reqData['stateid'] != 14 || $reqData['laststateid'] != 8) {
+		return array('status' => 'error',
+		             'errorcode' => 51,
+		             'errormsg' => 'reservation not in valid state');
+	}
+	# check that not a cluster reservation
+	if(count($reqData['reservations']) > 1) {
+		return array('status' => 'error',
+		             'errorcode' => 48,
+		             'errormsg' => 'cannot image a cluster reservation');
+	}
+	require_once(".ht-inc/images.php");
+	$imageid = $reqData['reservations'][0]['imageid'];
+	$imageData = getImages(0, $imageid);
+	$captime = unixToDatetime(time());
+	$comments = "start: {$reqData['start']}<br>"
+	          . "end: {$reqData['end']}<br>"
+	          . "computer: {$reqData['reservations'][0]['reservedIP']}<br>"
+	          . "capture time: $captime";
+	# create new revision if requestor is owner and not a kickstart image
+	if($imageData[$imageid]['installtype'] != 'kickstart' &&
+	   $reqData['userid'] == $imageData[$imageid]['ownerid']) {
+		$rc = updateExistingImage($requestid, $reqData['userid'], $comments, 1);
+		if($rc == 0) {
+			return array('status' => 'error',
+			             'errorcode' => 49,
+			             'errormsg' => 'error encountered while attempting to create new revision');
+		}
+	}
+	# create a new image if requestor is not owner or a kickstart image
+	else {
+		$ownerdata = getUserInfo($reqData['userid'], 1, 1);
+		$desc = "This is an autocaptured image.<br>"
+		      . "captured from image: {$reqData['reservations'][0]['prettyimage']}<br>"
+		      . "captured on: $captime<br>"
+		      . "owner: {$ownerdata['unityid']}@{$ownerdata['affiliation']}<br>";
+		$data = array('requestid' => $requestid,
+		              'description' => $desc,
+		              'usage' => '',
+		              'owner' => "{$ownerdata['unityid']}@{$ownerdata['affiliation']}",
+		              'prettyname' => "Autocaptured ({$ownerdata['unityid']} - $requestid)",
+		              'minram' => 64,
+		              'minprocnumber' => 1,
+		              'minprocspeed' => 500,
+		              'minnetwork' => 10,
+		              'maxconcurrent' => '',
+		              'checkuser' => 1,
+		              'rootaccess' => 1,
+		              'sysprep' => 1,
+		              'comments' => $comments);
+		$rc = submitAddImage($data, 1);
+		if($rc == 0) {
+			return array('status' => 'error',
+			             'errorcode' => 50,
+			             'errormsg' => 'error encountered while attempting to create image');
+		}
+	}
+	return array('status' => 'success');
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn XMLRPCtest($string)
 ///
 /// \param $string - a string

Modified: incubator/vcl/trunk/web/css/vcl.css
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/css/vcl.css?rev=1097842&r1=1097841&r2=1097842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/css/vcl.css (original)
+++ incubator/vcl/trunk/web/css/vcl.css Fri Apr 29 15:34:22 2011
@@ -215,6 +215,10 @@
 	color: red;
 }
 
+.rederrormsg {
+	color: red;
+}
+
 #revisiontable th {
 	border: solid 1px #000000;
 	padding: 2px;
@@ -260,3 +264,6 @@
 #savestatus {
 	color: #008000;
 }
+.noicon {
+	display: none;
+}

Modified: incubator/vcl/trunk/web/js/images.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/images.js?rev=1097842&r1=1097841&r2=1097842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/js/images.js (original)
+++ incubator/vcl/trunk/web/js/images.js Fri Apr 29 15:34:22 2011
@@ -19,6 +19,28 @@ var allgroups = '';
 var allcompgroups = '';
 var allimggroups = '';
 
+function RPCwrapper(data, CB, dojson) {
+	if(dojson) {
+		dojo.xhrPost({
+			url: 'index.php',
+			load: CB,
+			handleAs: "json",
+			error: errorHandler,
+			content: data,
+			timeout: 15000
+		});
+	}
+	else {
+		dojo.xhrPost({
+			url: 'index.php',
+			load: CB,
+			error: errorHandler,
+			content: data,
+			timeout: 15000
+		});
+	}
+}
+
 function addRemItem(cont, objid1, objid2, cb) {
    document.body.style.cursor = 'wait';
 	var obj = document.getElementById(objid1);
@@ -34,16 +56,10 @@ function addRemItem(cont, objid1, objid2
 	}
 	if(listids == "")
 		return;
-	dojo.xhrPost({
-		url: 'index.php',
-		load: cb,
-		handleAs: "json",
-		error: errorHandler,
-		content: {continuation: cont,
-					 listids: listids,
-					 id: id},
-		timeout: 15000
-	});
+	var data = {continuation: cont,
+	            listids: listids,
+	            id: id};
+	RPCwrapper(data, cb, 1);
 }
 
 function addRemGroup2(data, ioArgs) {
@@ -287,15 +303,9 @@ function getImagesButton() {
 
 	obj = document.getElementById('imgcont');
 
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: imagesCallback,
-		error: errorHandler,
-		content: {continuation: obj.value,
-					 groupid: groupid},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            groupid: groupid};
+	RPCwrapper(data, imagesCallback, 1);
 }
 
 function imagesCallback(data, ioArgs) {
@@ -330,15 +340,9 @@ function getGroupsButton() {
 
 	obj = document.getElementById('grpcont');
 
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: groupsCallback,
-		error: errorHandler,
-		content: {continuation: obj.value,
-					 imageid: imageid},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            imageid: imageid};
+	RPCwrapper(data, groupsCallback, 1);
 }
 
 function groupsCallback(data, ioArgs) {
@@ -373,15 +377,9 @@ function getMapCompGroupsButton() {
 
 	obj = document.getElementById('compcont');
 
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: mapCompGroupsCB,
-		error: errorHandler,
-		content: {continuation: obj.value,
-					 imagegrpid: imagegrpid},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            imagegrpid: imagegrpid};
+	RPCwrapper(data, mapCompGroupsCB, 1);
 }
 
 function mapCompGroupsCB(data, ioArgs) {
@@ -416,15 +414,9 @@ function getMapImgGroupsButton() {
 
 	obj = document.getElementById('imgcont');
 
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: mapImgGroupsCB,
-		error: errorHandler,
-		content: {continuation: obj.value,
-					 compgrpid: compgrpid},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            compgrpid: compgrpid};
+	RPCwrapper(data, mapImgGroupsCB, 1);
 }
 
 function mapImgGroupsCB(data, ioArgs) {
@@ -446,27 +438,16 @@ function generalCB(data, ioArgs) {
 
 function updateRevisionProduction(cont) {
    document.body.style.cursor = 'wait';
-	dojo.xhrPost({
-		url: 'index.php',
-		load: generalCB,
-		error: errorHandler,
-		content: {continuation: cont},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            imagegrpid: imagegrpid};
+	RPCwrapper({continuation: cont}, generalCB);
 }
 
 function updateRevisionComments(id, cont) {
    document.body.style.cursor = 'wait';
-	var comments = dijit.byId(id).value;
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: updateRevisionCommentsCB,
-		error: errorHandler,
-		content: {continuation: cont,
-					 comments: comments},
-		timeout: 15000
-	});
+	var data = {continuation: obj.value,
+	            comments: dijit.byId(id).value};
+	RPCwrapper(data, updateRevisionCommentsCB, 1);
 }
 
 function updateRevisionCommentsCB(data, ioArgs) {
@@ -493,15 +474,9 @@ function deleteRevisions(cont, idlist) {
 	if(checkedids.length == 0)
 		return;
 	checkedids = checkedids.join(',');
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: deleteRevisionsCB,
-		error: errorHandler,
-		content: {continuation: cont,
-					 checkedids: checkedids},
-		timeout: 15000
-	});
+	var data = {continuation: cont,
+	            checkedids: checkedids};
+	RPCwrapper(data, deleteRevisionsCB, 1);
 }
 
 function deleteRevisionsCB(data, ioArgs) {
@@ -511,15 +486,9 @@ function deleteRevisionsCB(data, ioArgs)
 
 function addSubimage() {
 	dijit.byId('addbtn').attr('label', 'Working...');
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: addSubimageCB,
-		error: errorHandler,
-		content: {continuation: dojo.byId('addsubimagecont').value,
-					 imageid: dijit.byId('addsubimagesel').value},
-		timeout: 15000
-	});
+	var data = {continuation: dojo.byId('addsubimagecont').value,
+	            imageid: dijit.byId('addsubimagesel').value};
+	RPCwrapper(data, addSubimageCB, 1);
 }
 
 function addSubimageCB(data, ioArgs) {
@@ -553,15 +522,9 @@ function remSubimages() {
 		return;
 	var ids = imgids.join(',');
 	dijit.byId('rembtn').attr('label', 'Working...');
-	dojo.xhrPost({
-		url: 'index.php',
-		handleAs: "json",
-		load: remSubimagesCB,
-		error: errorHandler,
-		content: {continuation: dojo.byId('remsubimagecont').value,
-					 imageids: ids},
-		timeout: 15000
-	});
+	var data = {continuation: dojo.byId('remsubimagecont').value,
+	            imageids: ids};
+	RPCwrapper(data, remSubimagesCB, 1);
 }
 
 function remSubimagesCB(data, ioArgs) {
@@ -586,3 +549,112 @@ function remSubimagesCB(data, ioArgs) {
 	dojo.byId('remsubimagecont').value = data.items.remcont;
 	dijit.byId('rembtn').attr('label', 'Remove Selected Subimage(s)');
 }
+
+function addConnectMethod() {
+	cmstore.fetch({
+		query: {name: dijit.byId('addcmsel').value},
+		onItem: addConnectMethod2
+	});
+}
+
+function addConnectMethod2(item) {
+	if(cmstore.getValue(item, 'autoprovisioned') == 0) {
+		dojo.byId('autoconfirmcontent').innerHTML = cmstore.getValue(item, 'display');
+		dijit.byId('autoconfirmdlg').show();
+		return;
+	}
+	addConnectMethod3();
+}
+
+function addConnectMethod3() {
+	dijit.byId('addcmbtn').attr('label', 'Working...');
+	var data = {continuation: dojo.byId('addcmcont').value,
+	            newid: dijit.byId('addcmsel').value};
+	RPCwrapper(data, addConnectMethodCB, 1);
+}
+
+function addConnectMethodCB(data, ioArgs) {
+	if(data.items.error) {
+		dijit.byId('addcmbtn').attr('label', 'Add Method');
+		alert(data.items.msg);
+		return;
+	}
+	cmstore.fetch({
+		query: {name: data.items.newid},
+		onItem: function(item) {
+			cmstore.setValue(item, 'active', 1);
+		}
+	});
+	dijit.byId('addcmsel').setStore(cmstore, '', {query: {active: 0}});
+	var obj = dojo.byId('curmethodsel');
+	dojo.byId('addcmcont').value = data.items.addcont;
+	dojo.byId('remcmcont').value = data.items.remcont;
+	var index = obj.options.length;
+	obj.options[index] = new Option(data.items.name, data.items.newid, false, false);
+	if(obj.options.length == cmstore._arrayOfAllItems.length) {
+		dijit.byId('addcmsel').set('disabled', true);
+		dijit.byId('addcmbtn').set('disabled', true);
+	}
+	sortSelect(obj);
+	updateConnectionMethodList();
+	dijit.byId('addcmbtn').attr('label', 'Add Method');
+}
+
+function remConnectMethod() {
+	var obj = dojo.byId('curmethodsel');
+	var cmids = new Array();
+	for(var i = obj.options.length - 1; i >= 0; i--) {
+		if(obj.options[i].selected)
+			cmids.push(obj.options[i].value);
+	}
+	if(! cmids.length)
+		return;
+	if(cmids.length == obj.options.length) {
+		dojo.byId('cmerror').innerHTML = 'There must be at least one item in Current Methods';
+		setTimeout(function() {dojo.byId('cmerror').innerHTML = '';}, 20000);
+		return;
+	}
+	var ids = cmids.join(',');
+	dijit.byId('remcmbtn').attr('label', 'Working...');
+	var data = {continuation: dojo.byId('remcmcont').value,
+	            ids: ids};
+	RPCwrapper(data, remConnectMethodCB, 1);
+}
+
+function remConnectMethodCB(data, ioArgs) {
+	if(dijit.byId('addcmsel').get('disabled')) {
+		dijit.byId('addcmsel').set('disabled', false);
+		dijit.byId('addcmbtn').set('disabled', false);
+	}
+	if(data.items.error) {
+		dijit.byId('rembtn').attr('label', 'Remove Selected Methods');
+		alert(data.items.msg);
+		return;
+	}
+	var obj = dojo.byId('curmethodsel');
+	for(var i = obj.options.length - 1; i >= 0; i--) {
+		if(obj.options[i].selected) {
+			cmstore.fetch({
+				query: {name: obj.options[i].value},
+				onItem: function(item) {
+					cmstore.setValue(item, 'active', 0);
+				}
+			});
+			obj.remove(i);
+		}
+	}
+	dijit.byId('addcmsel').setStore(cmstore, '', {query: {active: 0}});
+	dojo.byId('addcmcont').value = data.items.addcont;
+	dojo.byId('remcmcont').value = data.items.remcont;
+	updateConnectionMethodList();
+	dijit.byId('remcmbtn').attr('label', 'Remove Selected Methods');
+}
+
+function updateConnectionMethodList() {
+	var options = dojo.byId('curmethodsel').options;
+	var items = new Array();
+	for(var i = 0; i < options.length; i++) {
+		items.push(options[i].text);
+	}
+	dojo.byId('connectmethodlist').innerHTML = items.join('<br>');
+}

Modified: incubator/vcl/trunk/web/js/requests.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/requests.js?rev=1097842&r1=1097841&r2=1097842&view=diff
==============================================================================
--- incubator/vcl/trunk/web/js/requests.js (original)
+++ incubator/vcl/trunk/web/js/requests.js Fri Apr 29 15:34:22 2011
@@ -21,7 +21,7 @@ function RPCwrapper(data, CB, dojson) {
 		dojo.xhrPost({
 			url: 'index.php',
 			load: CB,
-			handleAs: "json-comment-filtered",
+			handleAs: "json",
 			error: errorHandler,
 			content: data,
 			timeout: 15000
@@ -83,6 +83,46 @@ function updateWaitTime(cleardesc) {
 	RPCwrapper(data, generalReqCB);
 }
 
+function selectLater() {
+	dojo.byId('laterradio').checked = true;
+}
+
+function selectDuration() {
+	if(dojo.byId('durationradio'))
+		dojo.byId('durationradio').checked = true;
+}
+
+function selectLength() {
+	if(dojo.byId('lengthradio'))
+		dojo.byId('lengthradio').checked = true;
+}
+
+function selectEnding() {
+	if(dojo.byId('dateradio'))
+		dojo.byId('dateradio').checked = true;
+}
+
+function setOpenEnd() {
+	if(! dijit.byId('openenddate').isValid() ||
+	   ! dijit.byId('openendtime').isValid()) {
+		dojo.byId('enddate').value = '';
+		return;
+	}
+	var d = dijit.byId('openenddate').value;
+	var t = dijit.byId('openendtime').value;
+	if(d == null || t == null) {
+		dojo.byId('enddate').value = '';
+		return;
+	}
+	dojo.byId('enddate').value = dojox.string.sprintf('%d-%02d-%02d %02d:%02d:00',
+	                             d.getFullYear(),
+	                             (d.getMonth() + 1),
+	                             d.getDate(),
+	                             t.getHours(),
+	                             t.getMinutes());
+	dojo.byId('openend').checked = true;
+}
+
 function checkValidImage() {
 	if(resSubmitted)
 		return false;
@@ -152,18 +192,14 @@ function resRefresh() {
 	if(! dojo.byId('resRefreshCont'))
 		return;
 	var contid = dojo.byId('resRefreshCont').value;
-	var reqid = dojo.byId('detailreqid').value;
-	if(! dijit.byId('resStatusPane')) {
-		window.location.reload();
-		return;
-	}
 	/*if(dojo.widget.byId('resStatusPane').windowState == 'minimized')
 		var incdetails = 0;
 	else*/
 		var incdetails = 1;
 	var data = {continuation: contid,
-	            incdetails: incdetails,
-	            reqid: reqid};
+	            incdetails: incdetails};
+	if(dojo.byId('detailreqid'))
+		data.reqid = dojo.byId('detailreqid').value;
 	RPCwrapper(data, generalReqCB);
 }
 
@@ -201,3 +237,242 @@ function showWindow(name) {
 	}
 	obj.show();
 }
+
+function endReservation(cont) {
+	RPCwrapper({continuation: cont}, endReservationCB, 1);
+}
+
+function endReservationCB(data, ioArgs) {
+	if(data.items.error) {
+		alert(data.items.msg);
+		return;
+	}
+	dojo.byId('endrescont').value = data.items.cont;
+	dojo.byId('endresid').value = data.items.requestid;
+	dojo.byId('endResDlgContent').innerHTML = data.items.content;
+	dijit.byId('endResDlgBtn').set('label', data.items.btntxt);
+	dijit.byId('endResDlg').show();
+}
+
+function submitDeleteReservation() {
+	if(dojo.byId('radioprod')) {
+		if(dojo.byId('radioprod').checked) {
+			var cont = dojo.byId('radioprod').value;
+			RPCwrapper({continuation: cont}, endReservationCB, 1);
+			return;
+		}
+		else if(dojo.byId('radioend').checked)
+			var data = {continuation: dojo.byId('radioend').value};
+		else
+			return;
+	}
+	else {
+		var data = {continuation: dojo.byId('endrescont').value};
+	}
+	dojo.byId('endResDlgContent').innerHTML = '';
+	dijit.byId('endResDlg').hide();
+   document.body.style.cursor = 'wait';
+	RPCwrapper(data, generalReqCB);
+}
+
+function editReservation(cont) {
+   document.body.style.cursor = 'wait';
+	RPCwrapper({continuation: cont}, editReservationCB, 1);
+}
+
+function editReservationCB(data, ioArgs) {
+	if(data.items.status == 'resgone') {
+		document.body.style.cursor = 'default';
+		dijit.byId('editResDlg').show();
+		resGone();
+		resRefresh();
+		return;
+	}
+	dojo.byId('editResDlgContent').innerHTML = data.items.html;
+	dojo.byId('editResDlgErrMsg').innerHTML = '';
+	AJdojoCreate('editResDlgContent');
+	if(data.items.status == 'nomodify') {
+		dijit.byId('editResDlgBtn').set('style', 'display: none');
+		dijit.byId('editResCancelBtn').set('label', 'Okay');
+	}
+	else {
+		dijit.byId('editResDlgBtn').set('style', 'display: inline');
+		dijit.byId('editResCancelBtn').set('label', 'Cancel');
+		dojo.byId('editrescont').value = data.items.cont;
+		dojo.byId('editresid').value = data.items.requestid;
+	}
+	dijit.byId('editResDlg').show();
+   document.body.style.cursor = 'default';
+}
+
+function hideEditResDlg() {
+	if(dijit.byId('day'))
+		dijit.byId('day').destroy();
+	if(dijit.byId('editstarttime'))
+		dijit.byId('editstarttime').destroy();
+	if(dijit.byId('length'))
+		dijit.byId('length').destroy();
+	if(dijit.byId('openenddate'))
+		dijit.byId('openenddate').destroy();
+	if(dijit.byId('openendtime'))
+		dijit.byId('openendtime').destroy();
+	dojo.byId('editResDlgErrMsg').innerHTML = '';
+	dojo.byId('editrescont').value = '';
+	dojo.byId('editresid').value = '';
+}
+
+function editResOpenEnd() {
+	if(! dijit.byId('openenddate').isValid() ||
+	   ! dijit.byId('openendtime').isValid()) {
+		dojo.byId('enddate').value = '';
+		return;
+	}
+	var d = dijit.byId('openenddate').value;
+	var t = dijit.byId('openendtime').value;
+	if(d == null || t == null) {
+		dojo.byId('enddate').value = '';
+		return;
+	}
+	dojo.byId('enddate').value = dojox.string.sprintf('%d-%02d-%02d %02d:%02d:00',
+	                             d.getFullYear(),
+	                             (d.getMonth() + 1),
+	                             d.getDate(),
+	                             t.getHours(),
+	                             t.getMinutes());
+}
+
+function submitEditReservation() {
+	var cont = dojo.byId('editrescont').value;
+	var data = {continuation: cont};
+	if(dijit.byId('day'))
+		data.day = dijit.byId('day').value;
+	if(dijit.byId('editstarttime')) {
+		var t = dijit.byId('editstarttime').value;
+		data.starttime = dojox.string.sprintf('%02d%02d', 
+		                                      t.getHours(),
+		                                      t.getMinutes());
+		var tmp = dijit.byId('day').value.match(/([0-9]{4})([0-9]{2})([0-9]{2})/);
+		var teststart = new Date(tmp[1], tmp[2] - 1, tmp[3], t.getHours(), t.getMinutes(), 0, 0);
+	}
+	if((! dojo.byId('dateradio') && ! dojo.byId('indefiniteradio') && dijit.byId('length')) ||
+	   (dojo.byId('lengthradio') && dojo.byId('lengthradio').checked)) {
+		data.length = dijit.byId('length').value;
+		data.endmode = 'length';
+	}
+	else if((dojo.byId('dateradio') && dojo.byId('dateradio').checked) ||
+	        (dijit.byId('openenddate') && ! dojo.byId('indefiniteradio')) || 
+	        (dijit.byId('openenddate') && dojo.byId('indefiniteradio') && ! dojo.byId('indefiniteradio').checked)) {
+		var d = dijit.byId('openenddate').value;
+		var t = dijit.byId('openendtime').value;
+		data.ending = dojox.string.sprintf('%d%02d%02d%02d%02d',
+		              d.getFullYear(),
+		              (d.getMonth() + 1),
+		              d.getDate(),
+		              t.getHours(),
+		              t.getMinutes());
+		data.endmode = 'ending';
+		var testend = new Date(d.getFullYear(), d.getMonth(), d.getDate(), t.getHours(), t.getMinutes(), 0, 0);
+		if(dijit.byId('editstarttime') && testend <= teststart) {
+			dojo.byId('editResDlgErrMsg').innerHTML = "The end time must be later than the start time.";
+			return;
+		}
+	}
+	else {
+		data.endmode = 'indefinite';
+	}
+	document.body.style.cursor = 'wait';
+	RPCwrapper(data, submitEditReservationCB, 1);
+}
+
+function submitEditReservationCB(data, ioArgs) {
+   document.body.style.cursor = 'default';
+	if(data.items.status == 'error') {
+		dojo.byId('editResDlgErrMsg').innerHTML = data.items.errmsg;
+		dojo.byId('editrescont').value = data.items.cont;
+		dojo.byId('editresid').value = '';
+		return;
+	}
+	else if(data.items.status == 'norequest') {
+		dojo.byId('editResDlgContent').innerHTML = data.items.html;
+		dojo.byId('editResDlgErrMsg').innerHTML = '';
+		dijit.byId('editResDlgBtn').set('style', 'display: none');
+		dijit.byId('editResCancelBtn').set('label', 'Okay');
+		resRefresh();
+		return;
+	}
+	dijit.byId('editResDlg').hide();
+	resRefresh();
+}
+
+function checkResGone(reqids) {
+	var editresid = dojo.byId('editresid').value;
+	if(editresid == '')
+		return;
+	for(var i = 0; i < reqids.length; i++) {
+		if(editresid == reqids[i])
+			return;
+	}
+	resGone();
+}
+
+function resGone() {
+	dojo.byId('editresid').value = '';
+	dojo.byId('editResDlgContent').innerHTML = "The reservation you selected<br>to edit has expired.<br><br>";
+	dojo.byId('editResDlgErrMsg').innerHTML = '';
+	dijit.byId('editResDlgBtn').set('style', 'display: none');
+	dijit.byId('editResCancelBtn').set('label', 'Okay');
+	if(dijit.byId('editResDlg')._relativePosition)
+		delete dijit.byId('editResDlg')._relativePosition;
+	dijit.byId('editResDlg')._position();
+}
+
+function hideRebReinstResDlg() {
+	dijit.byId('rebootreinstalldlg').set('title', 'Reboot Reservation');
+	dojo.byId('rebreinstResDlgContent').innerHTML = '';
+	dojo.removeClass('rebootRadios', 'hidden');
+	dojo.byId('softreboot').checked = true;
+	dojo.byId('rebreinstrescont').value = '';
+	//dojo.byId('rebreinstresid').value = '';
+	dojo.byId('rebreinstResDlgErrMsg').innerHTML = '';
+	dijit.byId('rebreinstResDlgBtn').set('label', 'Reboot Reservation');
+}
+
+function rebootRequest(cont) {
+	dijit.byId('rebootreinstalldlg').set('title', 'Reboot Reservation');
+	var txt = 'You can select either a soft or a hard reboot. A soft reboot<br>'
+	        + 'issues a reboot command to the operating system. A hard reboot<br>'
+	        + 'is akin to toggling the power switch on a computer. After<br>'
+	        + 'issuing the reboot, it may take several minutes before the<br>'
+	        + 'machine is available again. It is also possible that it will<br>'
+	        + 'not come back up at all. Are you sure you want to continue?<br><br>';
+	dojo.removeClass('rebootRadios', 'hidden');
+	dojo.byId('rebreinstResDlgContent').innerHTML = txt;
+	dojo.byId('rebreinstrescont').value = cont;
+	dijit.byId('rebreinstResDlgBtn').set('label', 'Reboot Reservation');
+	dijit.byId('rebootreinstalldlg').show();
+}
+
+function reinstallRequest(cont) {
+	dijit.byId('rebootreinstalldlg').set('title', 'Reinstall Reservation');
+	var txt = 'This will cause the reserved machine to be reinstalled. Any<br>'
+	        + 'data saved only to the reserved machine will be lost. Are<br>'
+	        + 'you sure you want to continue?<br><br>';
+	dojo.addClass('rebootRadios', 'hidden');
+	dojo.byId('rebreinstResDlgContent').innerHTML = txt;
+	dojo.byId('rebreinstrescont').value = cont;
+	dijit.byId('rebreinstResDlgBtn').set('label', 'Reinstall Reservation');
+	dijit.byId('rebootreinstalldlg').show();
+}
+
+function submitRebReinstReservation() {
+	var data = {continuation: dojo.byId('rebreinstrescont').value};
+	document.body.style.cursor = 'wait';
+	if(dijit.byId('rebreinstResDlgBtn').get('label') == 'Reboot Reservation') {
+		if(dojo.byId('hardreboot').checked)
+			data.reboottype = 1;
+		else
+			data.reboottype = 0;
+	}
+	dijit.byId('rebootreinstalldlg').hide();
+	RPCwrapper(data, generalReqCB);
+}

Added: incubator/vcl/trunk/web/js/serverprofiles.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/serverprofiles.js?rev=1097842&view=auto
==============================================================================
--- incubator/vcl/trunk/web/js/serverprofiles.js (added)
+++ incubator/vcl/trunk/web/js/serverprofiles.js Fri Apr 29 15:34:22 2011
@@ -0,0 +1,655 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+var profilesstoredata = {
+	identifier: 'id',
+	label: 'name',
+	items: []
+}
+var allprofiles = '';
+var allgroups = '';
+
+function RPCwrapper(data, CB, dojson) {
+	if(dojson) {
+		dojo.xhrPost({
+			url: 'index.php',
+			load: CB,
+			handleAs: "json",
+			error: errorHandler,
+			content: data,
+			timeout: 15000
+		});
+	}
+	else {
+		dojo.xhrPost({
+			url: 'index.php',
+			load: CB,
+			error: errorHandler,
+			content: data,
+			timeout: 15000
+		});
+	}
+}
+
+function generalReqCB(data, ioArgs) {
+	eval(data);
+	document.body.style.cursor = 'default';
+}
+
+function populateProfileStore(cont) {
+	RPCwrapper({continuation: cont}, populateProfileStoreCB, 1);
+}
+
+function populateProfileStoreCB(data, ioArgs) {
+	var store = profilesstore;
+	for(var i = 0; i < data.items.length; i++) {
+		store.newItem({id: data.items[i].id, name: data.items[i].name, desc: data.items[i].desc});
+	}
+	dijit.byId('deployprofileid').setStore(profilesstore, '', {query: {id:new RegExp("^(?:(?!70000).)*$")}});
+	dijit.byId('profileid').setStore(profilesstore, '', {query: {id:new RegExp("^(?:(?!70000).)*$")}});
+	dijit.byId('profiles').setStore(profilesstore, '', {query: {id:new RegExp("^(?:(?!70000).)*$")}});
+	getGroups();
+}
+
+function selectProfileChanged() {
+	if(dijit.byId('profileid').get('value') == 70000)
+		return;
+	dojo.addClass('serverprofiledata', 'hidden');
+	dijit.byId('fetchProfilesBtn').set('disabled', false);
+	dijit.byId('delProfilesBtn').set('disabled', false);
+	if(dijit.byId('profileid').getOptions(0).value == 70000)
+		dijit.byId('profileid').setStore(profilesstore, '', {query: {id:new RegExp("^(?:(?!70000).)*$")}});
+}
+
+function deployProfileChanged() {
+	profilesstore.fetch({
+		query: {id: dijit.byId('deployprofileid').get('value')},
+		onItem: function(item, request) {
+			var desc = profilesstore.getValue(item, 'desc');
+			if(desc == '') {
+				desc = '(No description)';
+			}
+			dojo.byId('deploydesc').innerHTML = desc;
+		}
+	});
+}
+
+function newServerProfile(cont) {
+	dijit.byId('profileid').setStore(profilesstore, '', {query: {id: '*'}});
+	dijit.byId('profileid').set('value', '70000');
+	clearProfileItems();
+	dijit.byId('fetchProfilesBtn').set('disabled', true);
+	dijit.byId('delProfilesBtn').set('disabled', true);
+	dojo.removeClass('serverprofiledata', 'hidden');
+}
+
+function clearProfileItems() {
+	dijit.byId('profilename').set('value', '');
+	dijit.byId('profiledesc').set('value', '');
+	dijit.byId('profileimage').reset();
+	dijit.byId('profilefixedIP').set('value', '');
+	dijit.byId('profilefixedMAC').set('value', '');
+	dijit.byId('profileadmingroup').reset();
+	dijit.byId('profilelogingroup').reset();
+	dijit.byId('profilemonitored').reset();
+}
+
+function saveServerProfile(cont) {
+	if((dijit.byId('profileimage') && ! dijit.byId('profileimage').isValid()) ||
+	   (dijit.byId('profileadmingroup') && ! dijit.byId('profileadmingroup').isValid()) ||
+	   (dijit.byId('profilelogingroup') && ! dijit.byId('profilelogingroup').isValid()) ||
+	   ! dijit.byId('profilefixedIP').isValid() ||
+	   ! dijit.byId('profilefixedMAC').isValid()) {
+		alert('Please correct the fields with invalid input');
+		return;
+	}
+	if(dijit.byId('profileimage'))
+		var imageid = dijit.byId('profileimage').get('value');
+	else
+		var imageid = dojo.byId('profileimage').value;
+	if(dijit.byId('profileadmingroup'))
+		var admingroupid = dijit.byId('profileadmingroup').get('value');
+	else
+		var admingroupid = dojo.byId('profileadmingroup').value;
+	if(dijit.byId('profilelogingroup'))
+		var logingroupid = dijit.byId('profilelogingroup').get('value');
+	else
+		var logingroupid = dojo.byId('profilelogingroup').value;
+	var data = {continuation: cont,
+	            id: dijit.byId('profileid').get('value'),
+	            name: dijit.byId('profilename').get('value'),
+	            desc: dijit.byId('profiledesc').get('value'),
+	            imageid: imageid,
+	            fixedIP: dijit.byId('profilefixedIP').get('value'),
+	            fixedMAC: dijit.byId('profilefixedMAC').get('value'),
+	            admingroupid: admingroupid,
+	            logingroupid: logingroupid,
+	            monitored: dijit.byId('profilemonitored').get('value')};
+	RPCwrapper(data, saveServerProfileCB, 1);
+}
+
+function saveServerProfileCB(data, ioArgs) {
+	if(data.items.error) {
+		alert(data.items.msg);
+		return;
+	}
+	var selobj = dijit.byId('profileid');
+	dijit.byId('profileid').setStore(profilesstore, '', {query: {id:new RegExp("^(?:(?!70000).)*$")}});
+	if(data.items.newprofile == 1) {
+		dojo.removeClass('serverprofiledata', 'hidden');
+		profilesstore.newItem({id: data.items.id,
+		                       name: data.items.name,
+		                       desc: data.items.desc});
+		selobj.set('value', data.items.id);
+		getProfiles();
+	}
+	else {
+		if(dijit.byId('deployprofileid').get('value') == data.items.id) {
+			var desc = data.items.desc;
+			if(data.items.desc == '') {
+				desc = '(No description)';
+			}
+			dojo.byId('deploydesc').innerHTML = desc;
+		}
+		var items = profilesstore.fetch({
+			query: {id: data.items.id},
+			newname: data.items.name,
+			newdesc: data.items.desc,
+			onItem: function(item, request) {
+				profilesstore.setValue(item, 'desc', request.newdesc);
+				if(profilesstore.getValue(item, 'name') != request.newname) {
+					profilesstore.setValue(item, 'name', request.newname);
+					getProfiles();
+				}
+			}
+		});
+	}
+	dojo.removeClass('savestatus', 'hidden');
+	dijit.byId('fetchProfilesBtn').set('disabled', false);
+	dijit.byId('delProfilesBtn').set('disabled', false);
+	setTimeout(clearSaveStatus, 10000);
+}
+
+function getServerProfileData(cont, id, cb) {
+	var data = {continuation: cont,
+	            id: dijit.byId(id).get('value')};
+	RPCwrapper(data, cb, 1);
+}
+
+function getServerProfileDataDeployCB(data, ioArgs) {
+	if(data.items.error) {
+		alert('You do not have access to apply this server profile.');
+		return;
+	}
+	dijit.byId('deployimage').set('value', data.items.imageid);
+	dijit.byId('deployfixedIP').set('value', data.items.fixedIP);
+	dijit.byId('deployfixedMAC').set('value', data.items.fixedMAC);
+	dijit.byId('deployadmingroup').set('value', data.items.admingroupid);
+	dijit.byId('deploylogingroup').set('value', data.items.logingroupid);
+	dijit.byId('deploymonitored').set('value', parseInt(data.items.monitored));
+}
+
+function getServerProfileDataManageCB(data, ioArgs) {
+	if(data.items.error) {
+		alert('You do not have access to modify this server profile.');
+		return;
+	}
+	clearProfileItems();
+	dijit.byId('profilename').set('value', data.items.name);
+	dijit.byId('profiledesc').set('value', data.items.description);
+	dijit.byId('profileimage').set('value', data.items.imageid);
+	dijit.byId('profilefixedIP').set('value', data.items.fixedIP);
+	dijit.byId('profilefixedMAC').set('value', data.items.fixedMAC);
+	dijit.byId('profileadmingroup').set('value', data.items.admingroupid);
+	dijit.byId('profilelogingroup').set('value', data.items.logingroupid);
+	dijit.byId('profilemonitored').set('value', parseInt(data.items.monitored));
+	dojo.removeClass('serverprofiledata', 'hidden');
+}
+
+function confirmDelServerProfile(cont) {
+	dojo.byId('delcont').value = cont;
+	dijit.byId('confirmDeleteProfile').show();
+}
+
+function delServerProfile() {
+	dijit.byId('confirmDeleteProfile').hide();
+	var data = {continuation: dojo.byId('delcont').value,
+	            id: dijit.byId('profileid').get('value')};
+	RPCwrapper(data, delServerProfileCB, 1);
+}
+
+function delServerProfileCB(data, ioArgs) {
+	if(data.items.error) {
+		alert(data.items.msg);
+		return;
+	}
+	clearProfileItems();
+	dojo.addClass('serverprofiledata', 'hidden');
+	profilesstore.fetch({
+		query: {id: data.items.id},
+		onItem: function(item, request) {
+			profilesstore.deleteItem(item);
+			dijit.byId('profileid').removeOption({value: item.id[0]});
+			dijit.byId('profiles').removeOption({value: item.id[0]});
+		}
+	});
+	getProfiles();
+}
+
+function clearSaveStatus() {
+	dojo.addClass('savestatus', 'hidden');
+}
+
+function getGroups() {
+   document.body.style.cursor = 'wait';
+	var selobj = dojo.byId('ingroups');
+	for(var i = selobj.options.length - 1; i >= 0; i--) {
+		selobj.remove(i);
+	}
+	selobj = dojo.byId('outgroups');
+	for(i = selobj.options.length - 1; i >= 0; i--) {
+		selobj.remove(i);
+	}
+
+	var profileid = dijit.byId('profiles').get('value');
+	if(profileid == '')
+		return;
+	profilesstore.fetch({
+		query: {id: profileid},
+		onItem: function(item, request) {
+			dojo.byId('inprofilename').innerHTML = item.name;
+			dojo.byId('outprofilename').innerHTML = item.name;
+		}
+	});
+	/*var obj = dijit.byId('profiles').getOptions(dijit.byId('profiles').get('value'));
+	if(! obj)
+		return;
+	var profilename = obj.label;
+
+	dojo.byId('inprofilename').innerHTML = profilename;
+	dojo.byId('outprofilename').innerHTML = profilename;*/
+
+	var data = {continuation: dojo.byId('grpcont').value,
+	            profileid: profileid};
+
+	RPCwrapper(data, getGroupsCB, 1);
+}
+
+function getGroupsCB(data, ioArgs) {
+	var obj = dojo.byId('ingroups');
+	for(var i = 0; i < data.items.ingroups.length; i++) {
+		obj.options[obj.options.length] = new Option(data.items.ingroups[i].name, data.items.ingroups[i].id);
+	}
+	obj = dojo.byId('outgroups');
+	for(var i = 0; i < data.items.outgroups.length; i++) {
+		obj.options[obj.options.length] = new Option(data.items.outgroups[i].name, data.items.outgroups[i].id);
+	}
+	allgroups = data.items.all;
+	dojo.removeClass('groupsdiv', 'hidden');
+	document.body.style.cursor = 'default';
+}
+
+function getProfiles() {
+   document.body.style.cursor = 'wait';
+	var selobj = dojo.byId('inprofiles');
+	for(var i = selobj.options.length - 1; i >= 0; i--) {
+		selobj.remove(i);
+	}
+	selobj = dojo.byId('outprofiles');
+	for(i = selobj.options.length - 1; i >= 0; i--) {
+		selobj.remove(i);
+	}
+
+	var obj = dijit.byId('profileGroups').getOptions(dijit.byId('profileGroups').get('value'));
+	var groupname = obj.label;
+
+	dojo.byId('ingroupname').innerHTML = groupname;
+	dojo.byId('outgroupname').innerHTML = groupname;
+
+	var data = {continuation: dojo.byId('profilecont').value,
+	            groupid: dijit.byId('profileGroups').get('value')};
+
+	RPCwrapper(data, getProfilesCB, 1);
+}
+
+function getProfilesCB(data, ioArgs) {
+	var obj = document.getElementById('inprofiles');
+	for(var i = 0; i < data.items.inprofiles.length; i++) {
+		obj.options[obj.options.length] = new Option(data.items.inprofiles[i].name, data.items.inprofiles[i].id);
+	}
+	obj = document.getElementById('outprofiles');
+	for(var i = 0; i < data.items.outprofiles.length; i++) {
+		obj.options[obj.options.length] = new Option(data.items.outprofiles[i].name, data.items.outprofiles[i].id);
+	}
+	allprofiles = data.items.all;
+	dojo.removeClass('profilesdiv', 'hidden');
+	document.body.style.cursor = 'default';
+}
+
+function addRemItem(cont, objid1, objid2, cb) {
+	var id = dijit.byId(objid1).get('value');
+
+	var obj = dojo.byId(objid2);
+	var listids = "";
+	for(var i = obj.options.length - 1; i >= 0; i--) {
+		if(obj.options[i].selected) {
+			listids = listids + ',' + obj.options[i].value;
+			obj.remove(i);
+		}
+	}
+	if(listids == "")
+		return;
+   document.body.style.cursor = 'wait';
+	var data = {continuation: cont,
+	            listids: listids,
+	            id: id};
+	RPCwrapper(data, cb, 1);
+}
+
+function addRemGroupCB(data, ioArgs) {
+	/*
+	for each profileid sent back we
+		search through allprofiles until we find it keeping track of the previous item with inout == 1
+		we set allprofiles[profileid].inout to 1
+		we find the previous item in the select.options array
+		we insert a new option right after that one
+	*/
+	var profiles = data.items.profiles;
+	var addrem = data.items.addrem; // 1 for add, 0 for rem
+	if(addrem == 0 && data.items.removedaccess == 1) {
+		var searchids = data.items.remprofileids.join('|');
+		var regex = new RegExp("(" + searchids + ")");
+		for(var i = profiles.length; i >= 0; i--) {
+			if(regex.test(allprofiles[i].id)) {
+				allprofiles.splice(i, 1);
+			}
+		}
+		profilesstore.fetch({
+			query: {id: regex},
+			onItem: function(item, request) {
+				profilesstore.deleteItem(item);
+				dijit.byId('profileid').removeOption({value: item.id[0]});
+				dijit.byId('profiles').removeOption({value: item.id[0]});
+			}
+		});
+	}
+	if(addrem)
+		var obj = document.getElementById('inprofiles');
+	else
+		var obj = document.getElementById('outprofiles');
+	for(var i = 0; i < profiles.length; i++) {
+		var lastid = -1;
+		for(var j = 0; j < allprofiles.length; j++) {
+			if(allprofiles[j].id == profiles[i]) {
+				if(addrem == 1)
+					allprofiles[j].inout = 1;
+				else
+					allprofiles[j].inout = 0;
+				if(lastid < 0) {
+					var before = obj.options[0];
+					var newoption = new Option(allprofiles[j].name, allprofiles[j].id);
+					try {
+						obj.add(newoption, before);
+					}
+					catch(ex) {
+						obj.add(newoption, 0);
+					}
+					break;
+				}
+				else {
+					for(var k = 0; k < obj.options.length; k++) {
+						if(obj.options[k].value == lastid) {
+							var before = obj.options[k + 1];
+							var newoption = new Option(allprofiles[j].name, allprofiles[j].id);
+							if(before)
+								try {
+									obj.add(newoption, before);
+								}
+								catch(ex) {
+									obj.add(newoption, k + 1);
+								}
+							else
+								obj.options[obj.options.length] = newoption;
+							break;
+						}
+					}
+				}
+				break;
+			}
+			if(allprofiles[j].inout == addrem)
+				lastid = allprofiles[j].id;
+		}
+	}
+	document.body.style.cursor = 'default';
+}
+
+function addRemProfileCB(data, ioArgs) {
+	var groups = data.items.groups;
+	var addrem = data.items.addrem; // 1 for add, 0 for rem
+	if(addrem)
+		var obj = dojo.byId('ingroups');
+	else
+		var obj = dojo.byId('outgroups');
+	for(var i = 0; i < groups.length; i++) {
+		var lastid = -1;
+		for(var j = 0; j < allgroups.length; j++) {
+			if(allgroups[j].id == groups[i]) {
+				if(addrem == 1)
+					allgroups[j].inout = 1;
+				else
+					allgroups[j].inout = 0;
+				if(lastid < 0) {
+					var before = obj.options[0];
+					var newoption = new Option(allgroups[j].name, allgroups[j].id);
+					try {
+						obj.add(newoption, before);
+					}
+					catch(ex) {
+						obj.add(newoption, 0);
+					}
+					break;
+				}
+				else {
+					for(var k = 0; k < obj.options.length; k++) {
+						if(obj.options[k].value == lastid) {
+							var before = obj.options[k + 1];
+							var newoption = new Option(allgroups[j].name, allgroups[j].id);
+							if(before)
+								try {
+									obj.add(newoption, before);
+								}
+								catch(ex) {
+									obj.add(newoption, k + 1);
+								}
+							else
+								obj.options[obj.options.length] = newoption;
+							break;
+						}
+					}
+				}
+				break;
+			}
+			if(allgroups[j].inout == addrem) {
+				lastid = allgroups[j].id;
+			}
+		}
+	}
+	if(addrem == 0 && data.items.removedaccess == 1) {
+		profilesstore.fetch({
+			query: {id: data.items.profileid},
+			onItem: function(item, request) {
+				profilesstore.deleteItem(item);
+				dijit.byId('profileid').removeOption({value: item.id[0]});
+				dijit.byId('profiles').removeOption({value: item.id[0]});
+				dojo.addClass('groupsdiv', 'hidden');
+				getProfiles();
+			}
+		});
+	}
+	document.body.style.cursor = 'default';
+}
+
+function setStartNow() {
+	dijit.byId('deploystarttime').set('required', false);
+	dijit.byId('deploystartdate').set('required', false);
+}
+
+function setStartLater() {
+	dojo.byId('startlater').checked = true;
+	dijit.byId('deploystarttime').set('required', true);
+	dijit.byId('deploystartdate').set('required', true);
+}
+
+function setEndIndef() {
+	dijit.byId('deployendtime').set('required', false);
+	dijit.byId('deployenddate').set('required', false);
+}
+
+function setEndAt() {
+	dojo.byId('endat').checked = true;
+	dijit.byId('deployendtime').set('required', true);
+	dijit.byId('deployenddate').set('required', true);
+}
+
+function submitDeploy() {
+	var cont = dojo.byId('deploycont').value;
+	if((dijit.byId('deployimage') && ! dijit.byId('deployimage').isValid()) ||
+	   (dijit.byId('deployadmingroup') && ! dijit.byId('deployadmingroup').isValid()) ||
+	   (dijit.byId('deploylogingroup') && ! dijit.byId('deploylogingroup').isValid())) {
+		alert('Please correct the fields with invalid input');
+		return;
+	}
+	if(dojo.byId('startlater').checked &&
+	   (! dijit.byId('deploystarttime').isValid() ||
+	   ! dijit.byId('deploystartdate').isValid())) {
+		dijit.byId('deploystarttime')._hasBeenBlurred = true;
+		dijit.byId('deploystarttime').validate();
+		dijit.byId('deploystartdate')._hasBeenBlurred = true;
+		dijit.byId('deploystartdate').validate();
+		alert('Please correct the fields with invalid input');
+		return;
+	}
+	if(dojo.byId('endat').checked &&
+	   (! dijit.byId('deployendtime').isValid() ||
+	   ! dijit.byId('deployenddate').isValid())) {
+		dijit.byId('deployendtime')._hasBeenBlurred = true;
+		dijit.byId('deployendtime').validate();
+		dijit.byId('deployenddate')._hasBeenBlurred = true;
+		dijit.byId('deployenddate').validate();
+		alert('Please correct the fields with invalid input');
+		return;
+	}
+	if(dojo.byId('startlater').checked) {
+		var today = new Date();
+		today.setMilliseconds(0);
+		var testday = dijit.byId('deploystartdate').get('value');
+		var tmp = dijit.byId('deploystarttime').get('value');
+		testday.setHours(tmp.getHours());
+		testday.setMinutes(tmp.getMinutes());
+		testday.setSeconds(tmp.getSeconds());
+		testday.setMilliseconds(tmp.getMilliseconds());
+		if(testday < today) {
+			alert('The starting time and date must be in the future.');
+			return;
+		}
+	}
+	if(dojo.byId('endat').checked) {
+		if(dojo.byId('startlater').checked) {
+			var teststart = dijit.byId('deploystartdate').get('value');
+			var tmp = dijit.byId('deploystarttime').get('value');
+			teststart.setHours(tmp.getHours());
+			teststart.setMinutes(tmp.getMinutes());
+			teststart.setSeconds(tmp.getSeconds());
+			teststart.setMilliseconds(tmp.getMilliseconds());
+		}
+		else {
+			var teststart = new Date();
+			teststart.setMilliseconds(0);
+		}
+		var testend = dijit.byId('deployenddate').get('value');
+		var tmp = dijit.byId('deployendtime').get('value');
+		testend.setHours(tmp.getHours());
+		testend.setMinutes(tmp.getMinutes());
+		testend.setSeconds(tmp.getSeconds());
+		testend.setMilliseconds(tmp.getMilliseconds());
+		if(testend <= teststart) {
+			alert('The ending time and date must be later than the starting time and date.');
+			return;
+		}
+	}
+	var data = {continuation: cont};
+	if(dijit.byId('deployimage'))
+		data.imageid = dijit.byId('deployimage').get('value');
+	else
+		data.imageid = dojo.byId('deployimage').value;
+	if(dijit.byId('deployadmingroup'))
+		data.admingroupid = dijit.byId('deployadmingroup').get('value');
+	else
+		data.admingroupid = dojo.byId('deployadmingroup').value;
+	if(dijit.byId('deploylogingroup'))
+		data.logingroupid = dijit.byId('deploylogingroup').get('value');
+	else
+		data.logingroupid = dojo.byId('deploylogingroup').value;
+	data.ipaddr = dijit.byId('deployfixedIP').get('value');
+	data.macaddr = dijit.byId('deployfixedMAC').get('value');
+	if(dijit.byId('deploymonitored').get('value') == 'on')
+		data.monitored = 1;
+	else
+		data.monitored = 0;
+	if(dojo.byId('startnow').checked) {
+		data.startmode = 0;
+	}
+	if(dojo.byId('startlater').checked) {
+		data.startmode = 1;
+		var time = dijit.byId('deploystarttime').get('value');
+		var date = dijit.byId('deploystartdate').get('value');
+		data.start = dojox.string.sprintf('%d%02d%02d%02d%02d',
+		                                  date.getFullYear(),
+		                                  date.getMonth() + 1,
+		                                  date.getDate(),
+		                                  time.getHours(),
+		                                  time.getMinutes());
+	}
+	if(dojo.byId('endindef').checked) {
+		data.endmode = 0;
+	}
+	if(dojo.byId('endat').checked) {
+		data.endmode = 1;
+		var time = dijit.byId('deployendtime').get('value');
+		var date = dijit.byId('deployenddate').get('value');
+		data.end = dojox.string.sprintf('%d%02d%02d%02d%02d',
+		                                date.getFullYear(),
+		                                date.getMonth() + 1,
+		                                date.getDate(),
+		                                time.getHours(),
+		                                time.getMinutes());
+	}
+	RPCwrapper(data, submitDeployCB, 1);
+}
+
+function submitDeployCB(data, ioArgs) {
+	if(data.items.error) {
+		alert(data.items.msg);
+		dojo.byId('deploycont').value = data.items.cont;
+		return;
+	}
+	if(data.items.success) {
+		window.location.href = data.items.redirecturl;
+	}
+}
+
+function updateWaitTime(a) {
+}