*$caption:"; echo " "; echo " \n"; } # # Spit the form out using the array of data. # function SPITFORM($formfields, $errors) { global $uid, $projlist, $isadmin, $types_result; global $TBDB_IMAGEID_IMAGENAMELEN, $TBDB_NODEIDLEN; if ($errors) { echo "\n"; while (list ($name, $message) = each ($errors)) { echo "\n"; } echo "
Oops, please fix the following errors!
$name:     $message

\n"; } # # Get the OSID list that the user has access to. Do not allow shared OSIDs, # since we want to force mere users to create thier own versions. # if ($isadmin) { $osid_result = DBQueryFatal("select * from os_info ". "where (path='' or path is NULL) and ". " version!='' and version is not NULL ". "order by osid"); } else { $osid_result = DBQueryFatal("select distinct o.* from os_info as o ". "left join group_membership as m ". " on m.pid=o.pid ". "where m.uid='$uid' and ". " (path='' or path is NULL) and ". " version!='' and version is not NULL ". "order by o.pid,o.osid"); } if (! mysql_num_rows($osid_result)) { USERERROR("There are no OS Descriptors that you are able to use!", 1); } echo "\n"; echo "
\n"; # # Select Project # echo "\n"; # # Image Name: # echo "\n"; # # Description # echo "\n"; # # Load Partition # echo "\n"; # # Load length # echo "\n"; WRITEOSIDMENU("Partition 1 OS[2]", "part1_osid", $osid_result, $formfields[part1_osid]); WRITEOSIDMENU("Partition 2 OS", "part2_osid", $osid_result, $formfields[part2_osid]); WRITEOSIDMENU("Partition 3 OS", "part3_osid", $osid_result, $formfields[part3_osid]); WRITEOSIDMENU("Partition 4 OS", "part4_osid", $osid_result, $formfields[part4_osid]); WRITEOSIDMENU("Boot OS[3]", "default_osid", $osid_result, $formfields[default_osid]); # # Path to image. # echo "\n"; # # Node Types. # echo "\n"; # # Node to Create image from. # echo "\n"; if ($isadmin) { # # Shared? # echo "\n"; # # Create mapping for this image. # echo "\n"; } echo "\n"; echo "
(Fields marked with * are required)
*Select Project: "; echo "
*Descriptor Name (no blanks):
*Description:
(a short pithy sentence)
*Starting DOS Partition:
(1-4, 0 means entire disk)
"; echo "
*Number of DOS Partitions[1]:
(1, 2, 3, or 4)
"; echo "
Filename (full path) of Image[4]:
(must reside in /proj)
Node Types[5]: \n"; mysql_data_seek($types_result, 0); while ($row = mysql_fetch_array($types_result)) { $type = $row[type]; $checked = ""; if (strcmp($formfields["mtype_$type"], "Yep") == 0) $checked = "checked"; echo " $type   \n"; } echo "
Node to Create Image from[6]:
Shared?:
(available to all projects)
Yes
Create Mapping?:
(insert osid to imageid mappings)
Yes
\n"; echo "

  1. Only single slices or partial disks are allowed. If you specify a non-zero starting load partition, the load load length must be one. If you specify zero for the starting load partition, then you can include any or all of the slices (1-4). Note that '0' means to start at the boot sector, while '1' means to start at the beginning of the first partition (typically starting at sector 63).
  2. If you are using a custom OS, you must create the OS Descriptor first!
  3. The OS (partition) that is active when the node boots up.
  4. The image file must reside in the project directory.
  5. Specify the node types that this image will be able to work on (ie: can be loaded on and expected to work).
  6. If you already have a node customized, enter that node name (pcXXX) and the image will be auto created for you. Notification of completion will be sent to you via email.

\n"; } # # On first load, display a virgin form and exit. # if (! $submit) { $defaults = array(); $defaults[loadpart] = "X"; $defaults[path] = "/proj/"; SPITFORM($defaults, 0); PAGEFOOTER(); return; } # # Otherwise, must validate and redisplay if errors # $errors = array(); if (!isset($formfields[pid]) || strcmp($formfields[pid], "") == 0) { $errors["Project"] = "Not Selected"; } elseif (!TBValidProject($formfields[pid])) { $errors["Project"] = "No such project"; } elseif (!TBProjAccessCheck($uid, $formfields[pid], $formfields[pid], $TB_PROJECT_MAKEIMAGEID)) { $errors["Project"] = "No enough permission"; } if (!isset($formfields[imagename]) || strcmp($formfields[imagename], "") == 0) { $errors["Descriptor Name"] = "Missing Field"; } else { if (! ereg("^[a-zA-Z0-9][-_a-zA-Z0-9\.]+$", $formfields[imagename])) { $errors["Descriptor Name"] = "Must be alphanumeric (includes _ and - and .)
". "and must begin with an alphanumeric"; } elseif (strlen($formfields[imagename]) > $TBDB_IMAGEID_IMAGENAMELEN) { $errors["Descriptor Name"] = "Too long! Must be less than or equal to $TBDB_UIDLEN"; } } if (!isset($formfields[description]) || strcmp($formfields[description], "") == 0) { $errors["Description"] = "Missing Field"; } if (!isset($formfields[loadpart]) || strcmp($formfields[loadpart], "") == 0 || strcmp($formfields[loadpart], "X") == 0) { $errors["Starting Partition"] = "Not Selected"; } elseif (! ereg("^[0-9]+$", $formfields[loadpart]) || $formfields[loadpart] < 0 || $formfields[loadpart] > 4) { $errors["Starting Partition"] = "Must be 0,1,2,3, or 4!"; } if (!isset($formfields[loadlength]) || strcmp($formfields[loadlength], "") == 0 || strcmp($formfields[loadlength], "X") == 0) { $errors["#of Partitions"] = "Not Selected"; } elseif (! ereg("^[0-9]+$", $formfields[loadlength]) || $formfields[loadlength] < 1 || $formfields[loadlength] > 4) { $errors["#of Partitions"] = "Must be 1,2,3, or 4!"; } elseif ($formfields[loadpart] != 0 && $formfields[loadlength] != 1) { $errors["#of Partitions"] = "Only single slices or
partial disks are allowed"; } # # Check sanity of the OSIDs for each slice. Permission checks not needed. # Store the ones we care about and silently forget about the extraneous # OSIDs by setting the locals to NULL. # # XXX This loops creates locals part1_osid, part2_osid, part3_osid, and # part4_osid on the fly. Look at $$foo. We use them below. # $osid_array = array(); for ($i = 1; $i <= 4; $i++) { $foo = "part${i}_osid"; # Local variable dynamically created. $thisosid = $formfields[$foo]; if (($formfields[loadpart] && $i == $formfields[loadpart]) || (!$formfields[loadpart] && $i <= $formfields[loadlength])) { if (!isset($thisosid) || strcmp($thisosid, "") == 0 || strcmp($thisosid, "X") == 0) { $errors["Partition $i OS"] = "Must select an OS"; } elseif (strcmp($thisosid, "none") == 0) { # # Allow admins to specify no OS for a partition. # if (!$isadmin) $errors["Partition $i OS"] = "Must select an OS"; $$foo = "NULL"; } elseif (!TBValidOSID($thisosid)) { $errors["Partition $i OS"] = "No such OS defined"; } else { $$foo = "'$thisosid'"; $osid_array[] = $thisosid; } } else { $$foo = "NULL"; } } # # Check the boot OS. Must be one of the OSes selected for a partition. # if (!isset($formfields[default_osid]) || strcmp($formfields[default_osid], "") == 0 || strcmp($formfields[default_osid], "none") == 0) { $errors["Boot OS"] = "Not Selected"; } elseif (!TBValidOSID($formfields[default_osid])) { $errors["Boot OS"] = "No such OS defined"; } else { for ($i = 0; $i < count($osid_array); $i++) { if (strcmp($osid_array[$i], $formfields[default_osid]) == 0) break; } if ($i == count($osid_array)) $errors["Boot OS"] = "Invalid; Must be one of the partitions"; } # # The path must not contain illegal chars and it must be more than # the original /proj/$pid we gave the user. We allow admins to specify # a path outside of /proj though. # if (!isset($formfields[path]) || strcmp($formfields[path], "") == 0) { $errors["Path"] = "Missing Field"; } elseif (! ereg("^[-_a-zA-Z0-9\/\.+]+$", $formfields[path])) { $errors["Path"] = "Contains invalid characters"; } else { $pdef = "/proj/$formfields[pid]/"; if (strcmp($formfields[path], "$pdef") == 0) { $errors["Path"] = "Incomplete Path"; } elseif (!$isadmin && strcmp(substr($formfields[path], 0, strlen($pdef)), $pdef)) { $errors["Path"] = "Invalid Path"; } } # # See what node types this image will work on. Must be at least one! # Store the valid types in a new array for simplicity. # $mtypes_array = array(); while ($row = mysql_fetch_array($types_result)) { $type = $row[type]; $foo = $formfields["mtype_$type"]; # # Look for a post variable with name. # if (isset($foo) && strcmp($foo, "Yep") == 0) { $mtypes_array[] = $type; } } if (! count($mtypes_array)) { $errors["Node Types"] = "Must select at least one type"; } # # Check sanity of node name and that user can create an image from it. # if (isset($formfields[node]) && strcmp($formfields[node], "")) { if (! TBValidNodeName($formfields[node])) { $errors["Node"] = "Invalid node name"; } if (! TBNodeAccessCheck($uid, $formfields[node], $TB_NODEACCESS_LOADIMAGE)) { $errors["Node"] = "Not enough permission"; } $node = $formfields[node]; } # # If any errors, respit the form with the current values and the # error messages displayed. Iterate until happy. # if (count($errors)) { SPITFORM($formfields, $errors); PAGEFOOTER(); return; } # # Only admins have this option. Always on for mereusers, but default off # for admins. # $makedefault = 0; if (! $isadmin || (isset($formfields[makedefault]) && strcmp($formfields[makedefault], "Yep") == 0)) { $makedefault = 1; } # # Only admin types can set the shared bit for an image. Ignore silently. # $shared = 0; if ($isadmin && isset($formfields[shared]) && strcmp($formfields[shared], "Yep") == 0) { $shared = 1; } # # For the rest, sanitize and convert to locals to make life easier. # $description = addslashes($formfields[description]); $pid = $formfields[pid]; $imagename = $formfields[imagename]; $loadpart = $formfields[loadpart]; $loadlength = $formfields[loadlength]; $default_osid= $formfields[default_osid]; $path = $formfields[path]; # # And insert the record! # DBQueryFatal("lock tables images write, osidtoimageid write"); # # Of course, the Image record may not already exist in the DB. # if (TBValidImage($pid, $imagename)) { DBQueryFatal("unlock tables"); $errors["Descriptor Name"] = "Already in use in selected project"; SPITFORM($formfields, $errors); PAGEFOOTER(); return; } # # Just concat them to form a unique imageid. # $imageid = "$pid-$imagename"; if (TBValidImageID($imageid)) { DBQueryFatal("unlock tables"); TBERROR("Could not form a unique imageid for $pid/$imagename!", 1); } # # Mereusers are not allowed to create more than one osid/imageid mapping # for each machinetype. They cannot actually do that through the EZ form # since the osid/imageid has to be unique, but it can happen by mixed # use of the long form and the short form, or with multiple uses of the # long form. # $typeclause = "type=" . "'$mtypes_array[0]'"; for ($i = 1; $i < count($mtypes_array); $i++) { $typeclause = "$typeclause or type=" . "'$mtypes_array[$i]'"; } $osidclause = "osid=" . "'$osid_array[0]'"; for ($i = 1; $i < count($osid_array); $i++) { $osidclause = "$osidclause or osid=" . "'$osid_array[$i]'"; } $query_result = DBQueryFatal("select osidtoimageid.*,images.pid,images.imagename ". " from osidtoimageid ". "left join images on ". " images.imageid=osidtoimageid.imageid ". "where ($osidclause) and ($typeclause)"); if (mysql_num_rows($query_result)) { if (!$isadmin || $makedefault) { DBQueryFatal("unlock tables"); echo "
There are other image descriptors that specify the same OS descriptors for the same node types.
There must be a unique mapping of OS descriptor to Image descriptor for each node type! Perhaps you need to delete one of the images below, or create a new OS descriptor to use in this new Image descriptor.

\n"; echo "\n"; echo "\n"; while ($row = mysql_fetch_array($query_result)) { $imageid = $row['imageid']; $url = rawurlencode($imageid); $osid = $row[osid]; $type = $row[type]; $imagename = $row[imagename]; echo "\n"; } echo "
OSID Type ImageID
$osid $type $imagename


\n"; USERERROR("Please check the other Image descriptors and make the ". "necessary changes!", 1); } } $query_result = DBQueryFatal("INSERT INTO images ". "(imagename, imageid, description, loadpart, loadlength, ". " part1_osid, part2_osid, part3_osid, part4_osid, ". " default_osid, path, pid, shared, creator, created) ". "VALUES ". " ('$imagename', '$imageid', '$description', $loadpart, ". " $loadlength, ". " $part1_osid, $part2_osid, $part3_osid, $part4_osid, ". " '$default_osid', '$path', '$pid', $shared, ". " '$uid', now())"); if (!$isadmin || $makedefault) { for ($i = 0; $i < count($mtypes_array); $i++) { for ($j = 0; $j < count($osid_array); $j++) { DBQueryFatal("REPLACE INTO osidtoimageid ". "(osid, type, imageid) ". "VALUES ('$osid_array[$j]', '$mtypes_array[$i]', ". " '$imageid')"); } } } DBQueryFatal("unlock tables"); SUBPAGESTART(); SUBMENUSTART("More Options"); if (! isset($node)) { $fooid = rawurlencode($imageid); WRITESUBMENUBUTTON("Edit this Image Descriptor", "editimageid_form.php3?imageid=$fooid"); WRITESUBMENUBUTTON("Delete this Image Descriptor", "deleteimageid.php3?imageid=$fooid"); } WRITESUBMENUBUTTON("Create a new Image Descriptor", "newimageid_explain.php3"); WRITESUBMENUBUTTON("Create a new OS Descriptor", "newosid_form.php3"); WRITESUBMENUBUTTON("Back to Image Descriptor list", "showimageid_list.php3"); WRITESUBMENUBUTTON("Back to OS Descriptor list", "showosid_list.php3"); SUBMENUEND(); # # Dump os_info record. # SHOWIMAGEID($imageid, 0); SUBPAGEEND(); if (isset($node)) { # # Create the image. # # XXX There is no locking of the descriptor or the node. Not really a # problem for the descriptor; the script is done with it by the time # it returns. However, if the node is freed up, things are going to go # awry. # # Grab the unix GID for running script. # TBGroupUnixInfo($pid, $pid, $unix_gid, $unix_name); echo "
Creating image using node '$node' ...

\n"; flush(); SUEXEC($uid, $unix_gid, "webcreateimage -p $pid $imagename $node", 1); echo "This will take 10 minutes or more; you will receive email notification when the image is complete. In the meantime, PLEASE DO NOT delete the imageid or the experiment $node is in. In fact, it is best if you do not mess the with the node at all!
\n"; } # # Standard Testbed Footer # PAGEFOOTER(); ?>